1
0
فهرست منبع

- Many small fixed for grunt to compile amber.
- Recompiled all js files using grunt

Nicolas Petton 12 سال پیش
والد
کامیت
3ed8b38659

+ 16 - 1
js/Canvas.deploy.js

@@ -1736,12 +1736,27 @@ smalltalk.method({
 selector: "initialize",
 selector: "initialize",
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+$1=_st(self)._isDOMAvailable();
+if(smalltalk.assert($1)){
 _st(self)._ensureCurrent();
 _st(self)._ensureCurrent();
+};
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HTMLSnippet.klass)})}
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HTMLSnippet.klass)})}
 }),
 }),
 smalltalk.HTMLSnippet.klass);
 smalltalk.HTMLSnippet.klass);
 
 
+smalltalk.addMethod(
+"_isDOMAvailable",
+smalltalk.method({
+selector: "isDOMAvailable",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return typeof document !== 'undefined' ;
+return self}, function($ctx1) {$ctx1.fill(self,"isDOMAvailable",{}, smalltalk.HTMLSnippet.klass)})}
+}),
+smalltalk.HTMLSnippet.klass);
+
 smalltalk.addMethod(
 smalltalk.addMethod(
 "_new",
 "_new",
 smalltalk.method({
 smalltalk.method({

+ 25 - 5
js/Canvas.js

@@ -2186,7 +2186,7 @@ smalltalk.HTMLCanvas.klass);
 
 
 
 
 smalltalk.addClass('HTMLSnippet', smalltalk.Object, ['snippets'], 'Canvas');
 smalltalk.addClass('HTMLSnippet', smalltalk.Object, ['snippets'], 'Canvas');
-smalltalk.HTMLSnippet.comment="HTMLSnippet instance is the registry of html snippets.\x0aHTMLSnippet current is the public singleton instance.\x0a\x0aAt the beginning, it scans the document for any html elements\x0awith 'data-snippet=\x22foo\x22' attribute and takes them off the document,\x0aremembering them in the store under the specified name.\x0aIt also install method #foo into HTMLCanvas dynamically.\x0a\x0aEvery html snippet should mark a 'caret', a place where contents\x0acan be inserted, by 'data-snippet=\x22*\x22' (a special name for caret).\x0aFor example:\x0a\x0a<li data-snippet='menuelement' class='...'><a data-snippet='*'></a></li>\x0a\x0adefines a list element with a link inside; the link itself is marked as a caret.\x0a\x0aYou can later issue\x0a\x0ahtml menuelement href: '/foo'; with: 'A foo'\x0a\x0ato insert the whole snippet and directly manipulate the caret, so it renders:\x0a\x0a<li class='...'><a href='/foo'>A foo</a></li>\x0a\x0aFor a self-careting tags (not very useful, but you do not need to fill class etc.\x0ayou can use\x0a\x0a<div class='lots of classes' attr1='one' attr2='two' data-snippet='*bar'></div>\x0a\x0aand in code later do:\x0a\x0ahtml bar with: [ xxx ]\x0a\x0ato render\x0a\x0a<div class='lots of classes' attr1='one' attr2='two'>...added by xxx...</div>\x0a"
+smalltalk.HTMLSnippet.comment="HTMLSnippet instance is the registry of html snippets.\x0aHTMLSnippet current is the public singleton instance.\x0a\x0aAt the beginning, it scans the document for any html elements\x0awith 'data-snippet=\x22foo\x22' attribute and takes them off the document,\x0aremembering them in the store under the specified name.\x0aIt also install method #foo into HTMLCanvas dynamically.\x0a\x0aEvery html snippet should mark a 'caret', a place where contents\x0acan be inserted, by 'data-snippet=\x22*\x22' (a special name for caret).\x0aFor example:\x0a\x0a<li data-snippet='menuelement' class='...'><a data-snippet='*'></a></li>\x0a\x0adefines a list element with a link inside; the link itself is marked as a caret.\x0a\x0aYou can later issue\x0a\x0ahtml menuelement href: '/foo'; with: 'A foo'\x0a\x0ato insert the whole snippet and directly manipulate the caret, so it renders:\x0a\x0a<li class='...'><a href='/foo'>A foo</a></li>\x0a\x0aFor a self-careting tags (not very useful, but you do not need to fill class etc.\x0ayou can use\x0a\x0a<div class='lots of classes' attr1='one' attr2='two' data-snippet='*bar'></div>\x0a\x0aand in code later do:\x0a\x0ahtml bar with: [ xxx ]\x0a\x0ato render\x0a\x0a<div class='lots of classes' attr1='one' attr2='two'>...added by xxx...</div>"
 smalltalk.addMethod(
 smalltalk.addMethod(
 "_initializeFromJQuery_",
 "_initializeFromJQuery_",
 smalltalk.method({
 smalltalk.method({
@@ -2306,7 +2306,7 @@ $1=$2;
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"snippets",{}, smalltalk.HTMLSnippet)})},
 }, function($ctx1) {$ctx1.fill(self,"snippets",{}, smalltalk.HTMLSnippet)})},
 args: [],
 args: [],
-source: "snippets\x0a\x09^snippets ifNil: [ snippets := #{} ]\x0a",
+source: "snippets\x0a\x09^snippets ifNil: [ snippets := #{} ]",
 messageSends: ["ifNil:"],
 messageSends: ["ifNil:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -2383,12 +2383,32 @@ selector: "initialize",
 category: 'initialization',
 category: 'initialization',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+return smalltalk.withContext(function($ctx1) { 
var $1;
+smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+$1=_st(self)._isDOMAvailable();
+if(smalltalk.assert($1)){
 _st(self)._ensureCurrent();
 _st(self)._ensureCurrent();
+};
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HTMLSnippet.klass)})},
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HTMLSnippet.klass)})},
 args: [],
 args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09self ensureCurrent",
-messageSends: ["initialize", "ensureCurrent"],
+source: "initialize\x0a\x09super initialize.\x0a    self isDOMAvailable ifTrue: [\x0a\x09\x09self ensureCurrent ]",
+messageSends: ["initialize", "ifTrue:", "ensureCurrent", "isDOMAvailable"],
+referencedClasses: []
+}),
+smalltalk.HTMLSnippet.klass);
+
+smalltalk.addMethod(
+"_isDOMAvailable",
+smalltalk.method({
+selector: "isDOMAvailable",
+category: 'instance creation',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 return typeof document !== 'undefined' ;
+return self}, function($ctx1) {$ctx1.fill(self,"isDOMAvailable",{}, smalltalk.HTMLSnippet.klass)})},
+args: [],
+source: "isDOMAvailable\x0a\x09< return typeof document !== 'undefined' >",
+messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.HTMLSnippet.klass);
 smalltalk.HTMLSnippet.klass);

+ 9 - 11
js/Compiler-Core.deploy.js

@@ -537,20 +537,18 @@ smalltalk.method({
 selector: "classNameFor:",
 selector: "classNameFor:",
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
 } else {
 } else {
-return _st(aClass)._name();
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
+} else {
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.AbstractCodeGenerator)})}
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.AbstractCodeGenerator)})}
 }),
 }),

+ 9 - 11
js/Compiler-Core.js

@@ -732,20 +732,18 @@ selector: "classNameFor:",
 category: 'accessing',
 category: 'accessing',
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
 } else {
 } else {
-return _st(aClass)._name();
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
+} else {
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.AbstractCodeGenerator)})},
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.AbstractCodeGenerator)})},
 args: ["aClass"],
 args: ["aClass"],

+ 14 - 4
js/Compiler-Exceptions.deploy.js

@@ -132,16 +132,26 @@ smalltalk.UnknownVariableError);
 
 
 
 
 smalltalk.addClass('RethrowErrorHandler', smalltalk.ErrorHandler, [], 'Compiler-Exceptions');
 smalltalk.addClass('RethrowErrorHandler', smalltalk.ErrorHandler, [], 'Compiler-Exceptions');
+smalltalk.addMethod(
+"_basicSignal_",
+smalltalk.method({
+selector: "basicSignal:",
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
throw anError;
+return self}, function($ctx1) {$ctx1.fill(self,"basicSignal:",{anError:anError}, smalltalk.RethrowErrorHandler)})}
+}),
+smalltalk.RethrowErrorHandler);
+
 smalltalk.addMethod(
 smalltalk.addMethod(
 "_handleError_",
 "_handleError_",
 smalltalk.method({
 smalltalk.method({
 selector: "handleError:",
 selector: "handleError:",
 fn: function (anError){
 fn: function (anError){
 var self=this;
 var self=this;
-smalltalk.send(self,"_handleError_",[anError],smalltalk.ErrorHandler);
-throw anError;
-;
-return self}
+return smalltalk.withContext(function($ctx1) { 
smalltalk.ErrorHandler.fn.prototype._handleError_.apply(_st(self), [anError]);
+_st(self)._basicSignal_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError}, smalltalk.RethrowErrorHandler)})}
 }),
 }),
 smalltalk.RethrowErrorHandler);
 smalltalk.RethrowErrorHandler);
 
 

+ 21 - 6
js/Compiler-Exceptions.js

@@ -185,6 +185,22 @@ smalltalk.UnknownVariableError);
 
 
 smalltalk.addClass('RethrowErrorHandler', smalltalk.ErrorHandler, [], 'Compiler-Exceptions');
 smalltalk.addClass('RethrowErrorHandler', smalltalk.ErrorHandler, [], 'Compiler-Exceptions');
 smalltalk.RethrowErrorHandler.comment="This class is used in the commandline version of the compiler.\x0aIt uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.\x0aAs a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted."
 smalltalk.RethrowErrorHandler.comment="This class is used in the commandline version of the compiler.\x0aIt uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.\x0aAs a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted."
+smalltalk.addMethod(
+"_basicSignal_",
+smalltalk.method({
+selector: "basicSignal:",
+category: 'error handling',
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
throw anError;
+return self}, function($ctx1) {$ctx1.fill(self,"basicSignal:",{anError:anError}, smalltalk.RethrowErrorHandler)})},
+args: ["anError"],
+source: "basicSignal: anError\x0a\x09<throw anError>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.RethrowErrorHandler);
+
 smalltalk.addMethod(
 smalltalk.addMethod(
 "_handleError_",
 "_handleError_",
 smalltalk.method({
 smalltalk.method({
@@ -192,13 +208,12 @@ selector: "handleError:",
 category: 'error handling',
 category: 'error handling',
 fn: function (anError){
 fn: function (anError){
 var self=this;
 var self=this;
-smalltalk.send(self,"_handleError_",[anError],smalltalk.ErrorHandler);
-throw anError;
-;
-return self},
+return smalltalk.withContext(function($ctx1) { 
smalltalk.ErrorHandler.fn.prototype._handleError_.apply(_st(self), [anError]);
+_st(self)._basicSignal_(anError);
+return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError}, smalltalk.RethrowErrorHandler)})},
 args: ["anError"],
 args: ["anError"],
-source: "handleError: anError\x0a\x09super handleError: anError.\x0a    <throw anError>",
-messageSends: ["handleError:"],
+source: "handleError: anError\x0a\x09super handleError: anError.\x0a    self basicSignal: anError",
+messageSends: ["handleError:", "basicSignal:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.RethrowErrorHandler);
 smalltalk.RethrowErrorHandler);

+ 44 - 66
js/Compiler-IR.deploy.js

@@ -36,32 +36,28 @@ selector: "aliasTemporally:",
 fn: function (aCollection){
 fn: function (aCollection){
 var self=this;
 var self=this;
 var threshold,result;
 var threshold,result;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$8,$7,$5,$9;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3,$5;
 threshold=(0);
 threshold=(0);
-$1=aCollection;
-$2=(function(each,i){
-return smalltalk.withContext(function($ctx2) {
$3=_st(each)._subtreeNeedsAliasing();
-if(smalltalk.assert($3)){
+_st(aCollection)._withIndexDo_((function(each,i){
+return smalltalk.withContext(function($ctx2) {
$1=_st(each)._subtreeNeedsAliasing();
+if(smalltalk.assert($1)){
 threshold=i;
 threshold=i;
 return threshold;
 return threshold;
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})});
-_st($1)._withIndexDo_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})}));
 result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
 result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
-$4=aCollection;
-$5=(function(each,i){
-return smalltalk.withContext(function($ctx2) {
$6=result;
-$8=_st(i).__lt_eq(threshold);
-if(smalltalk.assert($8)){
-$7=_st(self)._alias_(each);
+_st(aCollection)._withIndexDo_((function(each,i){
+return smalltalk.withContext(function($ctx2) {
$2=result;
+$4=_st(i).__lt_eq(threshold);
+if(smalltalk.assert($4)){
+$3=_st(self)._alias_(each);
 } else {
 } else {
-$7=_st(self)._visit_(each);
+$3=_st(self)._visit_(each);
 };
 };
-return _st($6)._add_($7);
-}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})});
-_st($4)._withIndexDo_($5);
-$9=result;
-return $9;
+return _st($2)._add_($3);
+}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})}));
+$5=result;
+return $5;
 }, function($ctx1) {$ctx1.fill(self,"aliasTemporally:",{aCollection:aCollection,threshold:threshold,result:result}, smalltalk.IRASTTranslator)})}
 }, function($ctx1) {$ctx1.fill(self,"aliasTemporally:",{aCollection:aCollection,threshold:threshold,result:result}, smalltalk.IRASTTranslator)})}
 }),
 }),
 smalltalk.IRASTTranslator);
 smalltalk.IRASTTranslator);
@@ -239,28 +235,23 @@ smalltalk.method({
 selector: "visitBlockSequenceNode:",
 selector: "visitBlockSequenceNode:",
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$8,$9,$6,$4,$1;
-$2=self;
-$3=_st((smalltalk.IRBlockSequence || IRBlockSequence))._new();
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aNode)._nodes();
-$6=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
+$1=_st(self)._withSequence_do_(_st((smalltalk.IRBlockSequence || IRBlockSequence))._new(),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(aNode)._nodes())._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx3) {
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx3) {
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx4) {
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 return smalltalk.withContext(function($ctx4) {
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})}));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})}));
-$7=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
-if(smalltalk.assert($7)){
+$2=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
+if(smalltalk.assert($2)){
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 } else {
 } else {
-$8=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
-_st($8)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
-$9=_st($8)._yourself();
-return _st(_st(self)._sequence())._add_($9);
+$3=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
+_st($3)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
+$4=_st($3)._yourself();
+return _st(_st(self)._sequence())._add_($4);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($5)._ifNotEmpty_($6);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._withSequence_do_($3,$4);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})}
 }, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})}
 }),
 }),
@@ -443,23 +434,18 @@ smalltalk.method({
 selector: "visitSequenceNode:",
 selector: "visitSequenceNode:",
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$6,$4,$1;
-$2=self;
-$3=_st((smalltalk.IRSequence || IRSequence))._new();
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aNode)._nodes();
-$6=(function(each){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$1=_st(self)._withSequence_do_(_st((smalltalk.IRSequence || IRSequence))._new(),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(aNode)._nodes())._do_((function(each){
 var instruction;
 var instruction;
 return smalltalk.withContext(function($ctx3) {
instruction=_st(self)._visit_(each);
 return smalltalk.withContext(function($ctx3) {
instruction=_st(self)._visit_(each);
 instruction;
 instruction;
-$7=_st(instruction)._isVariable();
-if(! smalltalk.assert($7)){
+$2=_st(instruction)._isVariable();
+if(! smalltalk.assert($2)){
 return _st(_st(self)._sequence())._add_(instruction);
 return _st(_st(self)._sequence())._add_(instruction);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({each:each,instruction:instruction},$ctx1)})});
-return _st($5)._do_($6);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._withSequence_do_($3,$4);
+}, function($ctx3) {$ctx3.fillBlock({each:each,instruction:instruction},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})}
 }, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})}
 }),
 }),
@@ -2025,38 +2011,30 @@ smalltalk.method({
 selector: "visitIRMethod:",
 selector: "visitIRMethod:",
 fn: function (anIRMethod){
 fn: function (anIRMethod){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$7,$9,$10,$8,$5,$3;
-$1=_st(self)._stream();
-$2=anIRMethod;
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(self)._stream();
-$5=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(self)._stream())._nextPutMethodDeclaration_with_(anIRMethod,(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._stream())._nextPutFunctionWith_arguments_((function(){
 return smalltalk.withContext(function($ctx3) {
_st(_st(self)._stream())._nextPutVars_(_st(_st(anIRMethod)._tempDeclarations())._collect_((function(each){
 return smalltalk.withContext(function($ctx3) {
_st(_st(self)._stream())._nextPutVars_(_st(_st(anIRMethod)._tempDeclarations())._collect_((function(each){
 return smalltalk.withContext(function($ctx4) {
return _st(_st(each)._name())._asVariableName();
 return smalltalk.withContext(function($ctx4) {
return _st(_st(each)._name())._asVariableName();
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})})));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})})));
-$6=_st(self)._stream();
-$7=anIRMethod;
-$8=(function(){
-return smalltalk.withContext(function($ctx4) {
$9=_st(_st(anIRMethod)._internalVariables())._notEmpty();
-if(smalltalk.assert($9)){
+return _st(_st(self)._stream())._nextPutContextFor_during_(anIRMethod,(function(){
+return smalltalk.withContext(function($ctx4) {
$1=_st(_st(anIRMethod)._internalVariables())._notEmpty();
+if(smalltalk.assert($1)){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 return smalltalk.withContext(function($ctx5) {
return _st(_st(each)._variable())._alias();
 return smalltalk.withContext(function($ctx5) {
return _st(_st(each)._variable())._alias();
 }, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})})));
 }, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})})));
 };
 };
-$10=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
-if(smalltalk.assert($10)){
+$2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
+if(smalltalk.assert($2)){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) {
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 return smalltalk.withContext(function($ctx5) {
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 }, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 }, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 } else {
 } else {
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})});
-return _st($6)._nextPutContextFor_during_($7,$8);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($4)._nextPutFunctionWith_arguments_($5,_st(anIRMethod)._arguments());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._nextPutMethodDeclaration_with_($2,$3);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}),_st(anIRMethod)._arguments());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:",{anIRMethod:anIRMethod}, smalltalk.IRJSTranslator)})}
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:",{anIRMethod:anIRMethod}, smalltalk.IRJSTranslator)})}
 }),
 }),
 smalltalk.IRJSTranslator);
 smalltalk.IRJSTranslator);

+ 44 - 66
js/Compiler-IR.js

@@ -43,32 +43,28 @@ category: 'visiting',
 fn: function (aCollection){
 fn: function (aCollection){
 var self=this;
 var self=this;
 var threshold,result;
 var threshold,result;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$8,$7,$5,$9;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3,$5;
 threshold=(0);
 threshold=(0);
-$1=aCollection;
-$2=(function(each,i){
-return smalltalk.withContext(function($ctx2) {
$3=_st(each)._subtreeNeedsAliasing();
-if(smalltalk.assert($3)){
+_st(aCollection)._withIndexDo_((function(each,i){
+return smalltalk.withContext(function($ctx2) {
$1=_st(each)._subtreeNeedsAliasing();
+if(smalltalk.assert($1)){
 threshold=i;
 threshold=i;
 return threshold;
 return threshold;
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})});
-_st($1)._withIndexDo_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})}));
 result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
 result=_st((smalltalk.OrderedCollection || OrderedCollection))._new();
-$4=aCollection;
-$5=(function(each,i){
-return smalltalk.withContext(function($ctx2) {
$6=result;
-$8=_st(i).__lt_eq(threshold);
-if(smalltalk.assert($8)){
-$7=_st(self)._alias_(each);
+_st(aCollection)._withIndexDo_((function(each,i){
+return smalltalk.withContext(function($ctx2) {
$2=result;
+$4=_st(i).__lt_eq(threshold);
+if(smalltalk.assert($4)){
+$3=_st(self)._alias_(each);
 } else {
 } else {
-$7=_st(self)._visit_(each);
+$3=_st(self)._visit_(each);
 };
 };
-return _st($6)._add_($7);
-}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})});
-_st($4)._withIndexDo_($5);
-$9=result;
-return $9;
+return _st($2)._add_($3);
+}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1)})}));
+$5=result;
+return $5;
 }, function($ctx1) {$ctx1.fill(self,"aliasTemporally:",{aCollection:aCollection,threshold:threshold,result:result}, smalltalk.IRASTTranslator)})},
 }, function($ctx1) {$ctx1.fill(self,"aliasTemporally:",{aCollection:aCollection,threshold:threshold,result:result}, smalltalk.IRASTTranslator)})},
 args: ["aCollection"],
 args: ["aCollection"],
 source: "aliasTemporally: aCollection\x0a\x09\x22https://github.com/NicolasPetton/amber/issues/296\x0a    \x0a    If a node is aliased, all preceding ones are aliased as well.\x0a    The tree is iterated twice. First we get the aliasing dependency, \x0a    then the aliasing itself is done\x22\x0a\x0a\x09| threshold result |\x0a    threshold := 0.\x0a    \x0a    aCollection withIndexDo: [ :each :i |\x0a        each subtreeNeedsAliasing\x0a\x09\x09    ifTrue: [ threshold := i ]].\x0a\x0a\x09result := OrderedCollection new.\x0a\x09aCollection withIndexDo: [ :each :i | \x0a\x09\x09result add: (i <= threshold\x0a\x09\x09\x09ifTrue: [ self alias: each ]\x0a\x09\x09\x09ifFalse: [ self visit: each ])].\x0a\x0a    ^result",
 source: "aliasTemporally: aCollection\x0a\x09\x22https://github.com/NicolasPetton/amber/issues/296\x0a    \x0a    If a node is aliased, all preceding ones are aliased as well.\x0a    The tree is iterated twice. First we get the aliasing dependency, \x0a    then the aliasing itself is done\x22\x0a\x0a\x09| threshold result |\x0a    threshold := 0.\x0a    \x0a    aCollection withIndexDo: [ :each :i |\x0a        each subtreeNeedsAliasing\x0a\x09\x09    ifTrue: [ threshold := i ]].\x0a\x0a\x09result := OrderedCollection new.\x0a\x09aCollection withIndexDo: [ :each :i | \x0a\x09\x09result add: (i <= threshold\x0a\x09\x09\x09ifTrue: [ self alias: each ]\x0a\x09\x09\x09ifFalse: [ self visit: each ])].\x0a\x0a    ^result",
@@ -306,28 +302,23 @@ selector: "visitBlockSequenceNode:",
 category: 'visiting',
 category: 'visiting',
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$8,$9,$6,$4,$1;
-$2=self;
-$3=_st((smalltalk.IRBlockSequence || IRBlockSequence))._new();
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aNode)._nodes();
-$6=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
+$1=_st(self)._withSequence_do_(_st((smalltalk.IRBlockSequence || IRBlockSequence))._new(),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(aNode)._nodes())._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx3) {
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx3) {
_st(_st(_st(aNode)._nodes())._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx4) {
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 return smalltalk.withContext(function($ctx4) {
return _st(_st(self)._sequence())._add_(_st(self)._visit_(each));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})}));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})}));
-$7=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
-if(smalltalk.assert($7)){
+$2=_st(_st(_st(aNode)._nodes())._last())._isReturnNode();
+if(smalltalk.assert($2)){
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 return _st(_st(self)._sequence())._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
 } else {
 } else {
-$8=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
-_st($8)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
-$9=_st($8)._yourself();
-return _st(_st(self)._sequence())._add_($9);
+$3=_st((smalltalk.IRBlockReturn || IRBlockReturn))._new();
+_st($3)._add_(_st(self)._visit_(_st(_st(aNode)._nodes())._last()));
+$4=_st($3)._yourself();
+return _st(_st(self)._sequence())._add_($4);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($5)._ifNotEmpty_($6);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._withSequence_do_($3,$4);
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})},
 }, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})},
 args: ["aNode"],
 args: ["aNode"],
@@ -550,23 +541,18 @@ selector: "visitSequenceNode:",
 category: 'visiting',
 category: 'visiting',
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$7,$6,$4,$1;
-$2=self;
-$3=_st((smalltalk.IRSequence || IRSequence))._new();
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aNode)._nodes();
-$6=(function(each){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$1=_st(self)._withSequence_do_(_st((smalltalk.IRSequence || IRSequence))._new(),(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(aNode)._nodes())._do_((function(each){
 var instruction;
 var instruction;
 return smalltalk.withContext(function($ctx3) {
instruction=_st(self)._visit_(each);
 return smalltalk.withContext(function($ctx3) {
instruction=_st(self)._visit_(each);
 instruction;
 instruction;
-$7=_st(instruction)._isVariable();
-if(! smalltalk.assert($7)){
+$2=_st(instruction)._isVariable();
+if(! smalltalk.assert($2)){
 return _st(_st(self)._sequence())._add_(instruction);
 return _st(_st(self)._sequence())._add_(instruction);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({each:each,instruction:instruction},$ctx1)})});
-return _st($5)._do_($6);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._withSequence_do_($3,$4);
+}, function($ctx3) {$ctx3.fillBlock({each:each,instruction:instruction},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})},
 }, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode}, smalltalk.IRASTTranslator)})},
 args: ["aNode"],
 args: ["aNode"],
@@ -2730,38 +2716,30 @@ selector: "visitIRMethod:",
 category: 'visiting',
 category: 'visiting',
 fn: function (anIRMethod){
 fn: function (anIRMethod){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$6,$7,$9,$10,$8,$5,$3;
-$1=_st(self)._stream();
-$2=anIRMethod;
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(self)._stream();
-$5=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(self)._stream())._nextPutMethodDeclaration_with_(anIRMethod,(function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._stream())._nextPutFunctionWith_arguments_((function(){
 return smalltalk.withContext(function($ctx3) {
_st(_st(self)._stream())._nextPutVars_(_st(_st(anIRMethod)._tempDeclarations())._collect_((function(each){
 return smalltalk.withContext(function($ctx3) {
_st(_st(self)._stream())._nextPutVars_(_st(_st(anIRMethod)._tempDeclarations())._collect_((function(each){
 return smalltalk.withContext(function($ctx4) {
return _st(_st(each)._name())._asVariableName();
 return smalltalk.withContext(function($ctx4) {
return _st(_st(each)._name())._asVariableName();
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})})));
 }, function($ctx4) {$ctx4.fillBlock({each:each},$ctx1)})})));
-$6=_st(self)._stream();
-$7=anIRMethod;
-$8=(function(){
-return smalltalk.withContext(function($ctx4) {
$9=_st(_st(anIRMethod)._internalVariables())._notEmpty();
-if(smalltalk.assert($9)){
+return _st(_st(self)._stream())._nextPutContextFor_during_(anIRMethod,(function(){
+return smalltalk.withContext(function($ctx4) {
$1=_st(_st(anIRMethod)._internalVariables())._notEmpty();
+if(smalltalk.assert($1)){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 _st(_st(self)._stream())._nextPutVars_(_st(_st(_st(anIRMethod)._internalVariables())._asArray())._collect_((function(each){
 return smalltalk.withContext(function($ctx5) {
return _st(_st(each)._variable())._alias();
 return smalltalk.withContext(function($ctx5) {
return _st(_st(each)._variable())._alias();
 }, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})})));
 }, function($ctx5) {$ctx5.fillBlock({each:each},$ctx1)})})));
 };
 };
-$10=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
-if(smalltalk.assert($10)){
+$2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
+if(smalltalk.assert($2)){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return _st(_st(self)._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) {
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 return smalltalk.withContext(function($ctx5) {
return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 }, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 }, function($ctx5) {$ctx5.fillBlock({},$ctx1)})}));
 } else {
 } else {
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})});
-return _st($6)._nextPutContextFor_during_($7,$8);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($4)._nextPutFunctionWith_arguments_($5,_st(anIRMethod)._arguments());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._nextPutMethodDeclaration_with_($2,$3);
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}),_st(anIRMethod)._arguments());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:",{anIRMethod:anIRMethod}, smalltalk.IRJSTranslator)})},
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:",{anIRMethod:anIRMethod}, smalltalk.IRJSTranslator)})},
 args: ["anIRMethod"],
 args: ["anIRMethod"],
 source: "visitIRMethod: anIRMethod\x0a\x0a\x09self stream\x0a\x09\x09nextPutMethodDeclaration: anIRMethod \x0a\x09\x09with: [ self stream \x0a\x09\x09\x09nextPutFunctionWith: [ \x0a            \x09self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |\x0a    \x09\x09\x09\x09each name asVariableName ]).\x0a            \x09self stream nextPutContextFor: anIRMethod during: [\x0a\x09\x09\x09\x09anIRMethod internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |\x0a\x09\x09\x09\x09\x09\x09each variable alias ]) ].\x0a\x09\x09\x09\x09anIRMethod scope hasNonLocalReturn \x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self stream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09\x09\x09\x09\x09\x09super visitIRMethod: anIRMethod ]]\x0a\x09\x09\x09\x09\x09ifFalse: [ super visitIRMethod: anIRMethod ]]]\x0a\x09\x09\x09arguments: anIRMethod arguments ]",
 source: "visitIRMethod: anIRMethod\x0a\x0a\x09self stream\x0a\x09\x09nextPutMethodDeclaration: anIRMethod \x0a\x09\x09with: [ self stream \x0a\x09\x09\x09nextPutFunctionWith: [ \x0a            \x09self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |\x0a    \x09\x09\x09\x09each name asVariableName ]).\x0a            \x09self stream nextPutContextFor: anIRMethod during: [\x0a\x09\x09\x09\x09anIRMethod internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |\x0a\x09\x09\x09\x09\x09\x09each variable alias ]) ].\x0a\x09\x09\x09\x09anIRMethod scope hasNonLocalReturn \x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self stream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09\x09\x09\x09\x09\x09super visitIRMethod: anIRMethod ]]\x0a\x09\x09\x09\x09\x09ifFalse: [ super visitIRMethod: anIRMethod ]]]\x0a\x09\x09\x09arguments: anIRMethod arguments ]",

+ 39 - 49
js/Compiler-Inlining.deploy.js

@@ -711,37 +711,33 @@ selector: "inlineClosure:",
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var inlinedClosure,sequence,statements;
 var inlinedClosure,sequence,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$5,$7;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 inlinedClosure=_st(self)._inlinedClosure();
 inlinedClosure=_st(self)._inlinedClosure();
 _st(inlinedClosure)._scope_(_st(anIRClosure)._scope());
 _st(inlinedClosure)._scope_(_st(anIRClosure)._scope());
-$1=_st(anIRClosure)._instructions();
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(each)._isSequence();
-if(! smalltalk.assert($3)){
+_st(_st(anIRClosure)._instructions())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(each)._isSequence();
+if(! smalltalk.assert($1)){
 return _st(inlinedClosure)._add_(each);
 return _st(inlinedClosure)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 sequence=_st(self)._inlinedSequence();
 sequence=_st(self)._inlinedSequence();
 _st(inlinedClosure)._add_(sequence);
 _st(inlinedClosure)._add_(sequence);
 statements=_st(_st(_st(anIRClosure)._instructions())._last())._instructions();
 statements=_st(_st(_st(anIRClosure)._instructions())._last())._instructions();
-$4=statements;
-$5=(function(){
+_st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
_st(_st(statements)._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
_st(_st(statements)._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx3) {
return _st(sequence)._add_(each);
 return smalltalk.withContext(function($ctx3) {
return _st(sequence)._add_(each);
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
-$6=_st(_st(_st(statements)._last())._isReturn())._and_((function(){
+$2=_st(_st(_st(statements)._last())._isReturn())._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(_st(statements)._last())._isBlockReturn();
 return smalltalk.withContext(function($ctx3) {
return _st(_st(statements)._last())._isBlockReturn();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($6)){
+if(smalltalk.assert($2)){
 return _st(sequence)._add_(_st(_st(_st(statements)._last())._instructions())._first());
 return _st(sequence)._add_(_st(_st(_st(statements)._last())._instructions())._first());
 } else {
 } else {
 return _st(sequence)._add_(_st(statements)._last());
 return _st(sequence)._add_(_st(statements)._last());
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($4)._ifNotEmpty_($5);
-$7=inlinedClosure;
-return $7;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=inlinedClosure;
+return $3;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,sequence:sequence,statements:statements}, smalltalk.IRSendInliner)})}
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,sequence:sequence,statements:statements}, smalltalk.IRSendInliner)})}
 }),
 }),
 smalltalk.IRSendInliner);
 smalltalk.IRSendInliner);
@@ -927,21 +923,19 @@ smalltalk.method({
 selector: "shouldInline:",
 selector: "shouldInline:",
 fn: function (anIRInstruction){
 fn: function (anIRInstruction){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 var $early={};
 var $early={};
 try {
 try {
 $1=_st(_st(self)._inlinedSelectors())._includes_(_st(anIRInstruction)._selector());
 $1=_st(_st(self)._inlinedSelectors())._includes_(_st(anIRInstruction)._selector());
 if(! smalltalk.assert($1)){
 if(! smalltalk.assert($1)){
 return false;
 return false;
 };
 };
-$2=_st(_st(anIRInstruction)._instructions())._allButFirst();
-$3=(function(each){
-return smalltalk.withContext(function($ctx2) {
$4=_st(each)._isClosure();
-if(! smalltalk.assert($4)){
+_st(_st(_st(anIRInstruction)._instructions())._allButFirst())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$2=_st(each)._isClosure();
+if(! smalltalk.assert($2)){
 throw $early=[false];
 throw $early=[false];
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($2)._do_($3);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return true;
 return true;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -1003,23 +997,21 @@ selector: "inlineClosure:",
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var inlinedClosure,statements;
 var inlinedClosure,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$5,$2,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
 inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
-$1=statements;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(statements)._last())._canBeAssigned();
-if(smalltalk.assert($3)){
-$4=_st((smalltalk.IRAssignment || IRAssignment))._new();
-_st($4)._add_(_st(_st(_st(self)._assignment())._instructions())._first());
-_st($4)._add_(_st(_st(statements)._last())._copy());
-$5=_st($4)._yourself();
-return _st(_st(statements)._last())._replaceWith_($5);
+_st(statements)._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(statements)._last())._canBeAssigned();
+if(smalltalk.assert($1)){
+$2=_st((smalltalk.IRAssignment || IRAssignment))._new();
+_st($2)._add_(_st(_st(_st(self)._assignment())._instructions())._first());
+_st($2)._add_(_st(_st(statements)._last())._copy());
+$3=_st($2)._yourself();
+return _st(_st(statements)._last())._replaceWith_($3);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotEmpty_($2);
-$6=inlinedClosure;
-return $6;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=inlinedClosure;
+return $4;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,statements:statements}, smalltalk.IRAssignmentInliner)})}
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,statements:statements}, smalltalk.IRAssignmentInliner)})}
 }),
 }),
 smalltalk.IRAssignmentInliner);
 smalltalk.IRAssignmentInliner);
@@ -1063,22 +1055,20 @@ selector: "inlineClosure:",
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var closure,statements;
 var closure,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$5,$2,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
 closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
-$1=statements;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(statements)._last())._isReturn();
-if(! smalltalk.assert($3)){
-$4=_st((smalltalk.IRReturn || IRReturn))._new();
-_st($4)._add_(_st(_st(statements)._last())._copy());
-$5=_st($4)._yourself();
-return _st(_st(statements)._last())._replaceWith_($5);
+_st(statements)._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(statements)._last())._isReturn();
+if(! smalltalk.assert($1)){
+$2=_st((smalltalk.IRReturn || IRReturn))._new();
+_st($2)._add_(_st(_st(statements)._last())._copy());
+$3=_st($2)._yourself();
+return _st(_st(statements)._last())._replaceWith_($3);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotEmpty_($2);
-$6=closure;
-return $6;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=closure;
+return $4;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,closure:closure,statements:statements}, smalltalk.IRReturnInliner)})}
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,closure:closure,statements:statements}, smalltalk.IRReturnInliner)})}
 }),
 }),
 smalltalk.IRReturnInliner);
 smalltalk.IRReturnInliner);

+ 39 - 49
js/Compiler-Inlining.js

@@ -951,37 +951,33 @@ category: 'inlining',
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var inlinedClosure,sequence,statements;
 var inlinedClosure,sequence,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4,$6,$5,$7;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 inlinedClosure=_st(self)._inlinedClosure();
 inlinedClosure=_st(self)._inlinedClosure();
 _st(inlinedClosure)._scope_(_st(anIRClosure)._scope());
 _st(inlinedClosure)._scope_(_st(anIRClosure)._scope());
-$1=_st(anIRClosure)._instructions();
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(each)._isSequence();
-if(! smalltalk.assert($3)){
+_st(_st(anIRClosure)._instructions())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(each)._isSequence();
+if(! smalltalk.assert($1)){
 return _st(inlinedClosure)._add_(each);
 return _st(inlinedClosure)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 sequence=_st(self)._inlinedSequence();
 sequence=_st(self)._inlinedSequence();
 _st(inlinedClosure)._add_(sequence);
 _st(inlinedClosure)._add_(sequence);
 statements=_st(_st(_st(anIRClosure)._instructions())._last())._instructions();
 statements=_st(_st(_st(anIRClosure)._instructions())._last())._instructions();
-$4=statements;
-$5=(function(){
+_st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
_st(_st(statements)._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
_st(_st(statements)._allButLast())._do_((function(each){
 return smalltalk.withContext(function($ctx3) {
return _st(sequence)._add_(each);
 return smalltalk.withContext(function($ctx3) {
return _st(sequence)._add_(each);
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
-$6=_st(_st(_st(statements)._last())._isReturn())._and_((function(){
+$2=_st(_st(_st(statements)._last())._isReturn())._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(_st(statements)._last())._isBlockReturn();
 return smalltalk.withContext(function($ctx3) {
return _st(_st(statements)._last())._isBlockReturn();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($6)){
+if(smalltalk.assert($2)){
 return _st(sequence)._add_(_st(_st(_st(statements)._last())._instructions())._first());
 return _st(sequence)._add_(_st(_st(_st(statements)._last())._instructions())._first());
 } else {
 } else {
 return _st(sequence)._add_(_st(statements)._last());
 return _st(sequence)._add_(_st(statements)._last());
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($4)._ifNotEmpty_($5);
-$7=inlinedClosure;
-return $7;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=inlinedClosure;
+return $3;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,sequence:sequence,statements:statements}, smalltalk.IRSendInliner)})},
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,sequence:sequence,statements:statements}, smalltalk.IRSendInliner)})},
 args: ["anIRClosure"],
 args: ["anIRClosure"],
 source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure sequence statements |\x0a\x0a\x09inlinedClosure := self inlinedClosure.\x0a\x09inlinedClosure scope: anIRClosure scope.\x0a\x0a\x09\x22Add the possible temp declarations\x22\x0a\x09anIRClosure instructions do: [ :each | \x0a\x09\x09each isSequence ifFalse: [\x0a\x09\x09\x09inlinedClosure add: each ]].\x0a\x0a\x09\x22Add a block sequence\x22\x0a\x09sequence := self inlinedSequence.\x0a\x09inlinedClosure add: sequence.\x0a\x0a\x09\x22Get all the statements\x22\x0a\x09statements := anIRClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements allButLast do: [ :each | sequence add: each ].\x0a\x0a\x09\x09\x22Inlined closures don't have implicit local returns\x22\x0a\x09\x09(statements last isReturn and: [ statements last isBlockReturn ])\x0a\x09\x09\x09ifTrue: [ sequence add: statements last instructions first ]\x0a\x09\x09\x09ifFalse: [ sequence add: statements last ] ].\x0a\x0a\x09^ inlinedClosure",
 source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure sequence statements |\x0a\x0a\x09inlinedClosure := self inlinedClosure.\x0a\x09inlinedClosure scope: anIRClosure scope.\x0a\x0a\x09\x22Add the possible temp declarations\x22\x0a\x09anIRClosure instructions do: [ :each | \x0a\x09\x09each isSequence ifFalse: [\x0a\x09\x09\x09inlinedClosure add: each ]].\x0a\x0a\x09\x22Add a block sequence\x22\x0a\x09sequence := self inlinedSequence.\x0a\x09inlinedClosure add: sequence.\x0a\x0a\x09\x22Get all the statements\x22\x0a\x09statements := anIRClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements allButLast do: [ :each | sequence add: each ].\x0a\x0a\x09\x09\x22Inlined closures don't have implicit local returns\x22\x0a\x09\x09(statements last isReturn and: [ statements last isBlockReturn ])\x0a\x09\x09\x09ifTrue: [ sequence add: statements last instructions first ]\x0a\x09\x09\x09ifFalse: [ sequence add: statements last ] ].\x0a\x0a\x09^ inlinedClosure",
@@ -1227,21 +1223,19 @@ selector: "shouldInline:",
 category: 'accessing',
 category: 'accessing',
 fn: function (anIRInstruction){
 fn: function (anIRInstruction){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 var $early={};
 var $early={};
 try {
 try {
 $1=_st(_st(self)._inlinedSelectors())._includes_(_st(anIRInstruction)._selector());
 $1=_st(_st(self)._inlinedSelectors())._includes_(_st(anIRInstruction)._selector());
 if(! smalltalk.assert($1)){
 if(! smalltalk.assert($1)){
 return false;
 return false;
 };
 };
-$2=_st(_st(anIRInstruction)._instructions())._allButFirst();
-$3=(function(each){
-return smalltalk.withContext(function($ctx2) {
$4=_st(each)._isClosure();
-if(! smalltalk.assert($4)){
+_st(_st(_st(anIRInstruction)._instructions())._allButFirst())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$2=_st(each)._isClosure();
+if(! smalltalk.assert($2)){
 throw $early=[false];
 throw $early=[false];
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($2)._do_($3);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return true;
 return true;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -1324,23 +1318,21 @@ category: 'inlining',
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var inlinedClosure,statements;
 var inlinedClosure,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$5,$2,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
 inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
-$1=statements;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(statements)._last())._canBeAssigned();
-if(smalltalk.assert($3)){
-$4=_st((smalltalk.IRAssignment || IRAssignment))._new();
-_st($4)._add_(_st(_st(_st(self)._assignment())._instructions())._first());
-_st($4)._add_(_st(_st(statements)._last())._copy());
-$5=_st($4)._yourself();
-return _st(_st(statements)._last())._replaceWith_($5);
+_st(statements)._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(statements)._last())._canBeAssigned();
+if(smalltalk.assert($1)){
+$2=_st((smalltalk.IRAssignment || IRAssignment))._new();
+_st($2)._add_(_st(_st(_st(self)._assignment())._instructions())._first());
+_st($2)._add_(_st(_st(statements)._last())._copy());
+$3=_st($2)._yourself();
+return _st(_st(statements)._last())._replaceWith_($3);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotEmpty_($2);
-$6=inlinedClosure;
-return $6;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=inlinedClosure;
+return $4;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,statements:statements}, smalltalk.IRAssignmentInliner)})},
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,inlinedClosure:inlinedClosure,statements:statements}, smalltalk.IRAssignmentInliner)})},
 args: ["anIRClosure"],
 args: ["anIRClosure"],
 source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure statements |\x0a\x0a\x09inlinedClosure := super inlineClosure: anIRClosure.\x0a\x09statements := inlinedClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last canBeAssigned ifTrue: [\x0a\x09\x09\x09statements last replaceWith: (IRAssignment new\x0a\x09\x09\x09\x09add: self assignment instructions first;\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself) ] ].\x0a\x0a\x09^ inlinedClosure",
 source: "inlineClosure: anIRClosure\x0a\x09| inlinedClosure statements |\x0a\x0a\x09inlinedClosure := super inlineClosure: anIRClosure.\x0a\x09statements := inlinedClosure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last canBeAssigned ifTrue: [\x0a\x09\x09\x09statements last replaceWith: (IRAssignment new\x0a\x09\x09\x09\x09add: self assignment instructions first;\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself) ] ].\x0a\x0a\x09^ inlinedClosure",
@@ -1400,22 +1392,20 @@ category: 'inlining',
 fn: function (anIRClosure){
 fn: function (anIRClosure){
 var self=this;
 var self=this;
 var closure,statements;
 var closure,statements;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$5,$2,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
 closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
-$1=statements;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(statements)._last())._isReturn();
-if(! smalltalk.assert($3)){
-$4=_st((smalltalk.IRReturn || IRReturn))._new();
-_st($4)._add_(_st(_st(statements)._last())._copy());
-$5=_st($4)._yourself();
-return _st(_st(statements)._last())._replaceWith_($5);
+_st(statements)._ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(statements)._last())._isReturn();
+if(! smalltalk.assert($1)){
+$2=_st((smalltalk.IRReturn || IRReturn))._new();
+_st($2)._add_(_st(_st(statements)._last())._copy());
+$3=_st($2)._yourself();
+return _st(_st(statements)._last())._replaceWith_($3);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotEmpty_($2);
-$6=closure;
-return $6;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$4=closure;
+return $4;
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,closure:closure,statements:statements}, smalltalk.IRReturnInliner)})},
 }, function($ctx1) {$ctx1.fill(self,"inlineClosure:",{anIRClosure:anIRClosure,closure:closure,statements:statements}, smalltalk.IRReturnInliner)})},
 args: ["anIRClosure"],
 args: ["anIRClosure"],
 source: "inlineClosure: anIRClosure\x0a\x09| closure statements |\x0a\x0a\x09closure := super inlineClosure: anIRClosure.\x0a\x09statements := closure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last isReturn\x0a\x09\x09\x09ifFalse: [ statements last replaceWith: (IRReturn new\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself)] ].\x0a\x0a\x09^ closure",
 source: "inlineClosure: anIRClosure\x0a\x09| closure statements |\x0a\x0a\x09closure := super inlineClosure: anIRClosure.\x0a\x09statements := closure instructions last instructions.\x0a\x09\x0a\x09statements ifNotEmpty: [\x0a\x09\x09statements last isReturn\x0a\x09\x09\x09ifFalse: [ statements last replaceWith: (IRReturn new\x0a\x09\x09\x09\x09add: statements last copy;\x0a\x09\x09\x09\x09yourself)] ].\x0a\x0a\x09^ closure",

+ 23 - 24
js/Compiler-Semantic.deploy.js

@@ -173,21 +173,22 @@ selector: "lookupVariable:",
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
 var lookup;
 var lookup;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 lookup=_st(self)._bindingFor_(aNode);
 lookup=_st(self)._bindingFor_(aNode);
 $1=lookup;
 $1=lookup;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(self)._outerScope();
-if(($receiver = $3) == nil || $receiver == undefined){
-lookup=$3;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(self)._outerScope();
+if(($receiver = $2) == nil || $receiver == undefined){
+lookup=$2;
 } else {
 } else {
 lookup=_st(_st(self)._outerScope())._lookupVariable_(aNode);
 lookup=_st(_st(self)._outerScope())._lookupVariable_(aNode);
 };
 };
-return lookup;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNil_($2);
-$4=lookup;
-return $4;
+lookup;
+} else {
+$1;
+};
+$3=lookup;
+return $3;
 }, function($ctx1) {$ctx1.fill(self,"lookupVariable:",{aNode:aNode,lookup:lookup}, smalltalk.LexicalScope)})}
 }, function($ctx1) {$ctx1.fill(self,"lookupVariable:",{aNode:aNode,lookup:lookup}, smalltalk.LexicalScope)})}
 }),
 }),
 smalltalk.LexicalScope);
 smalltalk.LexicalScope);
@@ -919,7 +920,7 @@ var self=this;
 var identifier;
 var identifier;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 identifier=_st(aNode)._value();
 identifier=_st(aNode)._value();
-$1=_st(_st(_st(["jQuery", "window", "process", "global"])._includes_(identifier))._not())._and_((function(){
+$1=_st(_st(_st(["jQuery", "window", "document", "process", "global"])._includes_(identifier))._not())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._isVariableGloballyUndefined_(identifier);
 return smalltalk.withContext(function($ctx2) {
return _st(self)._isVariableGloballyUndefined_(identifier);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 if(smalltalk.assert($1)){
 if(smalltalk.assert($1)){
@@ -1216,24 +1217,22 @@ smalltalk.method({
 selector: "visitSendNode:",
 selector: "visitSendNode:",
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 $1=_st(_st(_st(aNode)._receiver())._value()).__eq("super");
 $1=_st(_st(_st(aNode)._receiver())._value()).__eq("super");
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
_st(aNode)._superSend_(true);
+if(smalltalk.assert($1)){
+_st(aNode)._superSend_(true);
 _st(_st(aNode)._receiver())._value_("self");
 _st(_st(aNode)._receiver())._value_("self");
 _st(_st(self)._superSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 _st(_st(self)._superSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
-return smalltalk.withContext(function($ctx3) {
return _st((smalltalk.Set || Set))._new();
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-return _st(_st(_st(self)._superSends())._at_(_st(aNode)._selector()))._add_(aNode);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(_st((smalltalk.IRSendInliner || IRSendInliner))._inlinedSelectors())._includes_(_st(aNode)._selector());
-if(smalltalk.assert($4)){
+return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(_st(self)._superSends())._at_(_st(aNode)._selector()))._add_(aNode);
+} else {
+$2=_st(_st((smalltalk.IRSendInliner || IRSendInliner))._inlinedSelectors())._includes_(_st(aNode)._selector());
+if(smalltalk.assert($2)){
 _st(aNode)._shouldBeInlined_(true);
 _st(aNode)._shouldBeInlined_(true);
-return _st(_st(aNode)._receiver())._shouldBeAliased_(true);
+_st(_st(aNode)._receiver())._shouldBeAliased_(true);
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifTrue_ifFalse_($2,$3);
 _st(_st(self)._messageSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 _st(_st(self)._messageSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));

+ 24 - 25
js/Compiler-Semantic.js

@@ -235,21 +235,22 @@ category: 'accessing',
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
 var lookup;
 var lookup;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 lookup=_st(self)._bindingFor_(aNode);
 lookup=_st(self)._bindingFor_(aNode);
 $1=lookup;
 $1=lookup;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(self)._outerScope();
-if(($receiver = $3) == nil || $receiver == undefined){
-lookup=$3;
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(self)._outerScope();
+if(($receiver = $2) == nil || $receiver == undefined){
+lookup=$2;
 } else {
 } else {
 lookup=_st(_st(self)._outerScope())._lookupVariable_(aNode);
 lookup=_st(_st(self)._outerScope())._lookupVariable_(aNode);
 };
 };
-return lookup;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNil_($2);
-$4=lookup;
-return $4;
+lookup;
+} else {
+$1;
+};
+$3=lookup;
+return $3;
 }, function($ctx1) {$ctx1.fill(self,"lookupVariable:",{aNode:aNode,lookup:lookup}, smalltalk.LexicalScope)})},
 }, function($ctx1) {$ctx1.fill(self,"lookupVariable:",{aNode:aNode,lookup:lookup}, smalltalk.LexicalScope)})},
 args: ["aNode"],
 args: ["aNode"],
 source: "lookupVariable: aNode\x0a\x09| lookup |\x0a\x09lookup := (self bindingFor: aNode).\x0a\x09lookup ifNil: [\x0a\x09\x09lookup := self outerScope ifNotNil: [ \x0a\x09\x09\x09(self outerScope lookupVariable: aNode) ]].\x0a\x09^ lookup",
 source: "lookupVariable: aNode\x0a\x09| lookup |\x0a\x09lookup := (self bindingFor: aNode).\x0a\x09lookup ifNil: [\x0a\x09\x09lookup := self outerScope ifNotNil: [ \x0a\x09\x09\x09(self outerScope lookupVariable: aNode) ]].\x0a\x09^ lookup",
@@ -1246,7 +1247,7 @@ var self=this;
 var identifier;
 var identifier;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 identifier=_st(aNode)._value();
 identifier=_st(aNode)._value();
-$1=_st(_st(_st(["jQuery", "window", "process", "global"])._includes_(identifier))._not())._and_((function(){
+$1=_st(_st(_st(["jQuery", "window", "document", "process", "global"])._includes_(identifier))._not())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._isVariableGloballyUndefined_(identifier);
 return smalltalk.withContext(function($ctx2) {
return _st(self)._isVariableGloballyUndefined_(identifier);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 if(smalltalk.assert($1)){
 if(smalltalk.assert($1)){
@@ -1259,7 +1260,7 @@ _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_s
 };
 };
 return self}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier}, smalltalk.SemanticAnalyzer)})},
 return self}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier}, smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
 args: ["aNode"],
-source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a    We allow four variable names in addition: `jQuery`, `window`, `process` and `global` \x0a    for nodejs and browser environments. \x0a    \x0a    This is only to make sure compilation works on both browser-based and nodejs environments.\x0a    The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a    identifier := aNode value.\x0a    \x0a\x09((#('jQuery' 'window' 'process' 'global') includes: identifier) not \x0a        and: [ self isVariableGloballyUndefined: identifier ]) \x0a        \x09ifTrue: [\x0a\x09\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09\x09signal ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09currentScope methodScope unknownVariables add: aNode value ]",
+source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a    We allow four variable names in addition: `jQuery`, `window`, `process` and `global` \x0a    for nodejs and browser environments. \x0a    \x0a    This is only to make sure compilation works on both browser-based and nodejs environments.\x0a    The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a    identifier := aNode value.\x0a    \x0a\x09((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not \x0a        and: [ self isVariableGloballyUndefined: identifier ]) \x0a        \x09ifTrue: [\x0a\x09\x09\x09\x09UnknownVariableError new\x0a\x09\x09\x09\x09\x09variableName: aNode value;\x0a\x09\x09\x09\x09\x09signal ]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09currentScope methodScope unknownVariables add: aNode value ]",
 messageSends: ["value", "ifTrue:ifFalse:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope", "and:", "isVariableGloballyUndefined:", "not", "includes:"],
 messageSends: ["value", "ifTrue:ifFalse:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope", "and:", "isVariableGloballyUndefined:", "not", "includes:"],
 referencedClasses: ["UnknownVariableError"]
 referencedClasses: ["UnknownVariableError"]
 }),
 }),
@@ -1633,24 +1634,22 @@ selector: "visitSendNode:",
 category: 'visiting',
 category: 'visiting',
 fn: function (aNode){
 fn: function (aNode){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 $1=_st(_st(_st(aNode)._receiver())._value()).__eq("super");
 $1=_st(_st(_st(aNode)._receiver())._value()).__eq("super");
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
_st(aNode)._superSend_(true);
+if(smalltalk.assert($1)){
+_st(aNode)._superSend_(true);
 _st(_st(aNode)._receiver())._value_("self");
 _st(_st(aNode)._receiver())._value_("self");
 _st(_st(self)._superSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 _st(_st(self)._superSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
-return smalltalk.withContext(function($ctx3) {
return _st((smalltalk.Set || Set))._new();
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-return _st(_st(_st(self)._superSends())._at_(_st(aNode)._selector()))._add_(aNode);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(_st((smalltalk.IRSendInliner || IRSendInliner))._inlinedSelectors())._includes_(_st(aNode)._selector());
-if(smalltalk.assert($4)){
+return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(_st(self)._superSends())._at_(_st(aNode)._selector()))._add_(aNode);
+} else {
+$2=_st(_st((smalltalk.IRSendInliner || IRSendInliner))._inlinedSelectors())._includes_(_st(aNode)._selector());
+if(smalltalk.assert($2)){
 _st(aNode)._shouldBeInlined_(true);
 _st(aNode)._shouldBeInlined_(true);
-return _st(_st(aNode)._receiver())._shouldBeAliased_(true);
+_st(_st(aNode)._receiver())._shouldBeAliased_(true);
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifTrue_ifFalse_($2,$3);
 _st(_st(self)._messageSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 _st(_st(self)._messageSends())._at_ifAbsentPut_(_st(aNode)._selector(),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.Set || Set))._new();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));

+ 7 - 7
js/Compiler-Tests.js

@@ -407,7 +407,7 @@ _st(_st(self)._interpreter())._step();
 _st(self)._assert_equals_(_st(_st(self)._interpreter())._result(),(3));
 _st(self)._assert_equals_(_st(_st(self)._interpreter())._result(),(3));
 return self}, function($ctx1) {$ctx1.fill(self,"testMessageSend",{}, smalltalk.ASTSteppingInterpreterTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testMessageSend",{}, smalltalk.ASTSteppingInterpreterTest)})},
 args: [],
 args: [],
-source: "testMessageSend\x0a\x09self interpret: 'foo 1 + 2'.\x0a    \x0a    \x22SequenceNode\x22\x0a    self interpreter step.\x0a    \x0a    \x22SendNode\x22\x0a    self interpreter step.\x0a    \x0a     \x22ValueNode\x22\x0a    self interpreter step.\x0a    self assert: self interpreter currentNode value equals: 1.\x0a    \x0a    \x22ValueNode\x22\x0a    self interpreter step.\x0a    self assert: self interpreter currentNode value equals: 2.\x0a    \x0a    \x22Result\x22\x0a    self interpreter step.\x0a    self assert: self interpreter result equals: 3\x0a\x09",
+source: "testMessageSend\x0a\x09self interpret: 'foo 1 + 2'.\x0a    \x0a    \x22SequenceNode\x22\x0a    self interpreter step.\x0a    \x0a    \x22SendNode\x22\x0a    self interpreter step.\x0a    \x0a     \x22ValueNode\x22\x0a    self interpreter step.\x0a    self assert: self interpreter currentNode value equals: 1.\x0a    \x0a    \x22ValueNode\x22\x0a    self interpreter step.\x0a    self assert: self interpreter currentNode value equals: 2.\x0a    \x0a    \x22Result\x22\x0a    self interpreter step.\x0a    self assert: self interpreter result equals: 3",
 messageSends: ["interpret:", "step", "interpreter", "assert:equals:", "value", "currentNode", "result"],
 messageSends: ["interpret:", "step", "interpreter", "assert:equals:", "value", "currentNode", "result"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -427,7 +427,7 @@ _st(_st(self)._interpreter())._step();
 _st(self)._assert_equals_(_st(_st(self)._interpreter())._result(),(1));
 _st(self)._assert_equals_(_st(_st(self)._interpreter())._result(),(1));
 return self}, function($ctx1) {$ctx1.fill(self,"testSimpleStepping",{}, smalltalk.ASTSteppingInterpreterTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testSimpleStepping",{}, smalltalk.ASTSteppingInterpreterTest)})},
 args: [],
 args: [],
-source: "testSimpleStepping\x0a\x09self interpret: 'foo 1'.\x0a    \x0a    \x22SequenceNode\x22\x0a    self interpreter step.\x0a    \x0a    self assert: self interpreter result isNil.\x0a    \x0a    \x22ValueNode\x22\x0a    self interpreter step.\x0a    \x0a    self assert: self interpreter result equals: 1\x0a    \x0a\x09",
+source: "testSimpleStepping\x0a\x09self interpret: 'foo 1'.\x0a    \x0a    \x22SequenceNode\x22\x0a    self interpreter step.\x0a    \x0a    self assert: self interpreter result isNil.\x0a    \x0a    \x22ValueNode\x22\x0a    self interpreter step.\x0a    \x0a    self assert: self interpreter result equals: 1",
 messageSends: ["interpret:", "step", "interpreter", "assert:", "isNil", "result", "assert:equals:"],
 messageSends: ["interpret:", "step", "interpreter", "assert:", "isNil", "result", "assert:equals:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -556,7 +556,7 @@ _st(self)._should_return_("foo | a | a := false ifTrue: [ 1 ]. ^ a",nil);
 _st(self)._should_return_("foo | a | ^ a := true ifTrue: [ 1 ]",(1));
 _st(self)._should_return_("foo | a | ^ a := true ifTrue: [ 1 ]",(1));
 return self}, function($ctx1) {$ctx1.fill(self,"testAssignment",{}, smalltalk.CodeGeneratorTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testAssignment",{}, smalltalk.CodeGeneratorTest)})},
 args: [],
 args: [],
-source: "testAssignment\x0a\x09self should: 'foo | a | a := true ifTrue: [ 1 ]. ^ a' return: 1.\x0a\x09self should: 'foo | a | a := false ifTrue: [ 1 ]. ^ a' return: nil.\x0a\x0a\x09self should: 'foo | a | ^ a := true ifTrue: [ 1 ]' return: 1 ",
+source: "testAssignment\x0a\x09self should: 'foo | a | a := true ifTrue: [ 1 ]. ^ a' return: 1.\x0a\x09self should: 'foo | a | a := false ifTrue: [ 1 ]. ^ a' return: nil.\x0a\x0a\x09self should: 'foo | a | ^ a := true ifTrue: [ 1 ]' return: 1",
 messageSends: ["should:return:"],
 messageSends: ["should:return:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -606,7 +606,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._should_return_("foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a",[(1), (2)]);
 return smalltalk.withContext(function($ctx1) { 
_st(self)._should_return_("foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a",[(1), (2)]);
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicArrayElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicArrayElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 args: [],
 args: [],
-source: "testDynamicArrayElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a' return: #(1 2).\x0a",
+source: "testDynamicArrayElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { x. true ifTrue: [ x := 2 ] }\x0a' return: #(1 2).",
 messageSends: ["should:return:"],
 messageSends: ["should:return:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -622,7 +622,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._should_return_("foo\x0a  | x |\x0a  x := 'foo'->1.\x0a  ^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([_st("foo").__minus_gt((1)),_st("bar").__minus_gt((2))]));
 return smalltalk.withContext(function($ctx1) { 
_st(self)._should_return_("foo\x0a  | x |\x0a  x := 'foo'->1.\x0a  ^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([_st("foo").__minus_gt((1)),_st("bar").__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 args: [],
 args: [],
-source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := ''foo''->1.\x0a  ^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.\x0a",
+source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := ''foo''->1.\x0a  ^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
 messageSends: ["should:return:", "->"],
 messageSends: ["should:return:", "->"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -641,7 +641,7 @@ _st(self)._should_return_("foo\x0a  | x |\x0a  x := 1.\x0a  ^ { 'foo'->x. 'bar'-
 _st(self)._should_return_("foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([_st("foo").__minus_gt((1)),_st("bar").__minus_gt((2))]));
 _st(self)._should_return_("foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_([_st("foo").__minus_gt((1)),_st("bar").__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testInnerTemporalDependentElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testInnerTemporalDependentElementsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 args: [],
 args: [],
-source: "testInnerTemporalDependentElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.\x0a",
+source: "testInnerTemporalDependentElementsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
 messageSends: ["should:return:", "->"],
 messageSends: ["should:return:", "->"],
 referencedClasses: ["Array"]
 referencedClasses: ["Array"]
 }),
 }),
@@ -760,7 +760,7 @@ return smalltalk.withContext(function($ctx1) { 
_st(self)._should_return_("foo\x
 _st(self)._should_return_("foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: x with: (true ifTrue: [ x := 2 ])\x0a",[(smalltalk.Array || Array),(2)]);
 _st(self)._should_return_("foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: x with: (true ifTrue: [ x := 2 ])\x0a",[(smalltalk.Array || Array),(2)]);
 return self}, function($ctx1) {$ctx1.fill(self,"testSendReceiverAndArgumentsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 return self}, function($ctx1) {$ctx1.fill(self,"testSendReceiverAndArgumentsOrdered",{}, smalltalk.CodeGeneratorTest)})},
 args: [],
 args: [],
-source: "testSendReceiverAndArgumentsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: x with: (true ifTrue: [ x := 2 ])\x0a' return: #(1 2).\x0a\x0a\x09self should: 'foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: x with: (true ifTrue: [ x := 2 ])\x0a' return: {Array. 2}.\x0a",
+source: "testSendReceiverAndArgumentsOrdered\x0a\x09self should: 'foo\x0a  | x |\x0a  x := 1.\x0a  ^ Array with: x with: (true ifTrue: [ x := 2 ])\x0a' return: #(1 2).\x0a\x0a\x09self should: 'foo\x0a  | x |\x0a  x := Array.\x0a  ^ x with: x with: (true ifTrue: [ x := 2 ])\x0a' return: {Array. 2}.",
 messageSends: ["should:return:"],
 messageSends: ["should:return:"],
 referencedClasses: ["Array"]
 referencedClasses: ["Array"]
 }),
 }),

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 270 - 104
js/Documentation.deploy.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 288 - 122
js/Documentation.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 320 - 376
js/IDE.deploy.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 244 - 290
js/IDE.js


+ 78 - 112
js/Importer-Exporter.deploy.js

@@ -7,30 +7,27 @@ selector: "nextChunk",
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
 var char,result,chunk;
 var char,result,chunk;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 var $early={};
 var $early={};
 try {
 try {
 result=_st("")._writeStream();
 result=_st("")._writeStream();
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
 return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
 char;
 char;
 return _st(char)._notNil();
 return _st(char)._notNil();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(char).__eq("!");
-$4=(function(){
-return smalltalk.withContext(function($ctx3) {
$5=_st(_st(self["@stream"])._peek()).__eq("!");
-if(smalltalk.assert($5)){
-return _st(self["@stream"])._next();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(char).__eq("!");
+if(smalltalk.assert($1)){
+$2=_st(_st(self["@stream"])._peek()).__eq("!");
+if(smalltalk.assert($2)){
+_st(self["@stream"])._next();
 } else {
 } else {
-$6=_st(_st(result)._contents())._trimBoth();
-throw $early=[$6];
+$3=_st(_st(result)._contents())._trimBoth();
+throw $early=[$3];
+};
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-_st($3)._ifTrue_($4);
 return _st(result)._nextPut_(char);
 return _st(result)._nextPut_(char);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileTrue_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return nil;
 return nil;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -71,20 +68,18 @@ smalltalk.method({
 selector: "classNameFor:",
 selector: "classNameFor:",
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
+} else {
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
 } else {
 } else {
-return _st(aClass)._name();
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})}
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})}
 }),
 }),
@@ -230,17 +225,15 @@ smalltalk.method({
 selector: "exportMethodsOf:on:",
 selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 fn: function (aClass,aStream){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
-$1=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
-}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})}));
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._category())._match_("^\x5c*");
-if(! smalltalk.assert($3)){
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._category())._match_("^\x5c*");
+if(! smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(aStream)._lf();
 _st(aStream)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})}
 }),
 }),
@@ -290,26 +283,20 @@ selector: "exportPackageExtensionsOf:on:",
 fn: function (package_,aStream){
 fn: function (package_,aStream){
 var self=this;
 var self=this;
 var name;
 var name;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 name=_st(package_)._name();
 name=_st(package_)._name();
-$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
-$4=(function(aClass){
-return smalltalk.withContext(function($ctx3) {
$5=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+_st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || 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(_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());
 return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
-}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})}));
-$6=(function(method){
-return smalltalk.withContext(function($ctx4) {
$7=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
-if(smalltalk.assert($7)){
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(method){
+return smalltalk.withContext(function($ctx4) {
$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})});
-return _st($5)._do_($6);
-}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
-return _st($3)._do_($4);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})}
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})}
 }),
 }),
 smalltalk.Exporter);
 smalltalk.Exporter);
@@ -336,20 +323,18 @@ smalltalk.method({
 selector: "classNameFor:",
 selector: "classNameFor:",
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
 } else {
 } else {
-return _st(aClass)._name();
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
+} else {
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})}
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})}
 }),
 }),
@@ -466,16 +451,14 @@ selector: "exportMethodsOf:on:",
 fn: function (aClass,aStream){
 fn: function (aClass,aStream){
 var self=this;
 var self=this;
 var map;
 var map;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 map=_st((smalltalk.Dictionary || Dictionary))._new();
 map=_st((smalltalk.Dictionary || Dictionary))._new();
-$1=aClass;
-$2=(function(category,methods){
-return smalltalk.withContext(function($ctx2) {
$3=_st(category)._match_("^\x5c*");
-if(! smalltalk.assert($3)){
+_st(aClass)._protocolsDo_((function(category,methods){
+return smalltalk.withContext(function($ctx2) {
$1=_st(category)._match_("^\x5c*");
+if(! smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 return _st(map)._at_put_(category,methods);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})});
-_st($1)._protocolsDo_($2);
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
 return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
@@ -509,22 +492,18 @@ selector: "exportPackageExtensionsOf:on:",
 fn: function (package_,aStream){
 fn: function (package_,aStream){
 var self=this;
 var self=this;
 var name,map;
 var name,map;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 name=_st(package_)._name();
 name=_st(package_)._name();
-$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
-$4=(function(aClass){
+_st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || 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) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
 map;
-$5=aClass;
-$6=(function(category,methods){
-return smalltalk.withContext(function($ctx4) {
$7=_st(category)._match_(_st("^\x5c*").__comma(name));
-if(smalltalk.assert($7)){
+_st(aClass)._protocolsDo_((function(category,methods){
+return smalltalk.withContext(function($ctx4) {
$1=_st(category)._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 return _st(map)._at_put_(category,methods);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})});
-_st($5)._protocolsDo_($6);
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
 return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
@@ -533,10 +512,8 @@ return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
 methods;
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
-}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
-return _st($3)._do_($4);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})}
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})}
 }),
 }),
 smalltalk.ChunkExporter);
 smalltalk.ChunkExporter);
@@ -608,33 +585,29 @@ selector: "import:",
 fn: function (aStream){
 fn: function (aStream){
 var self=this;
 var self=this;
 var chunk,result,parser,lastEmpty;
 var chunk,result,parser,lastEmpty;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$6,$5,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
 lastEmpty=false;
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 chunk;
 chunk;
 return _st(chunk)._isNil();
 return _st(chunk)._isNil();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(chunk)._isEmpty();
-$4=(function(){
-return smalltalk.withContext(function($ctx3) {
lastEmpty=true;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(chunk)._isEmpty();
+if(smalltalk.assert($1)){
+lastEmpty=true;
 return lastEmpty;
 return lastEmpty;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-$5=(function(){
-return smalltalk.withContext(function($ctx3) {
result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
+} else {
+result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
 result;
 result;
-$6=lastEmpty;
-if(smalltalk.assert($6)){
+$2=lastEmpty;
+if(smalltalk.assert($2)){
 lastEmpty=false;
 lastEmpty=false;
 lastEmpty;
 lastEmpty;
 return _st(result)._scanFrom_(parser);
 return _st(result)._scanFrom_(parser);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($3)._ifTrue_ifFalse_($4,$5);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileFalse_($2);
+};
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})}
 return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})}
 }),
 }),
 smalltalk.Importer);
 smalltalk.Importer);
@@ -664,23 +637,16 @@ selector: "loadPackage:prefix:",
 fn: function (packageName,aString){
 fn: function (packageName,aString){
 var self=this;
 var self=this;
 var url;
 var url;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$8,$7,$6,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
-$1=jQuery;
-$2=url;
-$4=_st("type").__minus_gt("GET");
-$5=_st("dataType").__minus_gt("script");
-$7=(function(jqXHR,textStatus){
-return smalltalk.withContext(function($ctx2) {
$8=_st(_st(jqXHR)._readyState()).__eq((4));
-if(smalltalk.assert($8)){
+_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._fromPairs_([_st("type").__minus_gt("GET"),_st("dataType").__minus_gt("script"),_st("complete").__minus_gt((function(jqXHR,textStatus){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(jqXHR)._readyState()).__eq((4));
+if(smalltalk.assert($1)){
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})});
-$6=_st("complete").__minus_gt($7);
-$3=smalltalk.HashedCollection._fromPairs_([$4,$5,$6,_st("error").__minus_gt((function(){
+}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),_st("error").__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
 return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
-_st($1)._ajax_options_($2,$3);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})}
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})}
 }),
 }),
 smalltalk.PackageLoader);
 smalltalk.PackageLoader);

+ 78 - 112
js/Importer-Exporter.js

@@ -8,30 +8,27 @@ category: 'reading',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
 var char,result,chunk;
 var char,result,chunk;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 var $early={};
 var $early={};
 try {
 try {
 result=_st("")._writeStream();
 result=_st("")._writeStream();
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
 return smalltalk.withContext(function($ctx2) {
char=_st(self["@stream"])._next();
 char;
 char;
 return _st(char)._notNil();
 return _st(char)._notNil();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(char).__eq("!");
-$4=(function(){
-return smalltalk.withContext(function($ctx3) {
$5=_st(_st(self["@stream"])._peek()).__eq("!");
-if(smalltalk.assert($5)){
-return _st(self["@stream"])._next();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileTrue_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(char).__eq("!");
+if(smalltalk.assert($1)){
+$2=_st(_st(self["@stream"])._peek()).__eq("!");
+if(smalltalk.assert($2)){
+_st(self["@stream"])._next();
 } else {
 } else {
-$6=_st(_st(result)._contents())._trimBoth();
-throw $early=[$6];
+$3=_st(_st(result)._contents())._trimBoth();
+throw $early=[$3];
+};
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-_st($3)._ifTrue_($4);
 return _st(result)._nextPut_(char);
 return _st(result)._nextPut_(char);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileTrue_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return nil;
 return nil;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -87,20 +84,18 @@ selector: "classNameFor:",
 category: 'private',
 category: 'private',
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
+} else {
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
 } else {
 } else {
-return _st(aClass)._name();
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})},
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.Exporter)})},
 args: ["aClass"],
 args: ["aClass"],
@@ -276,17 +271,15 @@ selector: "exportMethodsOf:on:",
 category: 'private',
 category: 'private',
 fn: function (aClass,aStream){
 fn: function (aClass,aStream){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
-$1=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
 return smalltalk.withContext(function($ctx2) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
-}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})}));
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._category())._match_("^\x5c*");
-if(! smalltalk.assert($3)){
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._category())._match_("^\x5c*");
+if(! smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 return _st(self)._exportMethod_of_on_(each,aClass,aStream);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(aStream)._lf();
 _st(aStream)._lf();
 return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 return self}, function($ctx1) {$ctx1.fill(self,"exportMethodsOf:on:",{aClass:aClass,aStream:aStream}, smalltalk.Exporter)})},
 args: ["aClass", "aStream"],
 args: ["aClass", "aStream"],
@@ -351,26 +344,20 @@ category: 'private',
 fn: function (package_,aStream){
 fn: function (package_,aStream){
 var self=this;
 var self=this;
 var name;
 var name;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 name=_st(package_)._name();
 name=_st(package_)._name();
-$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
-$4=(function(aClass){
-return smalltalk.withContext(function($ctx3) {
$5=_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
+_st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || 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(_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());
 return smalltalk.withContext(function($ctx4) {
return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
-}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})}));
-$6=(function(method){
-return smalltalk.withContext(function($ctx4) {
$7=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
-if(smalltalk.assert($7)){
+}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(method){
+return smalltalk.withContext(function($ctx4) {
$1=_st(_st(method)._category())._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($1)){
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 return _st(self)._exportMethod_of_on_(method,aClass,aStream);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})});
-return _st($5)._do_($6);
-}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
-return _st($3)._do_($4);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})},
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name}, smalltalk.Exporter)})},
 args: ["package", "aStream"],
 args: ["package", "aStream"],
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22Issue #143: sort classes and methods alphabetically\x22\x0a\x0a\x09| name |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass | \x0a\x09\x09\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |\x0a\x09\x09\x09\x09(method category match: '^\x5c*', name) ifTrue: [\x0a\x09\x09\x09\x09\x09self exportMethod: method of: aClass on: aStream ]]]]",
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22Issue #143: sort classes and methods alphabetically\x22\x0a\x0a\x09| name |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass | \x0a\x09\x09\x09((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |\x0a\x09\x09\x09\x09(method category match: '^\x5c*', name) ifTrue: [\x0a\x09\x09\x09\x09\x09self exportMethod: method of: aClass on: aStream ]]]]",
@@ -407,20 +394,18 @@ selector: "classNameFor:",
 category: 'not yet classified',
 category: 'not yet classified',
 fn: function (aClass){
 fn: function (aClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$5,$4,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(aClass)._isMetaclass();
 $2=_st(aClass)._isMetaclass();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
return _st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$4=(function(){
-return smalltalk.withContext(function($ctx2) {
$5=_st(aClass)._isNil();
-if(smalltalk.assert($5)){
-return "nil";
+if(smalltalk.assert($2)){
+$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(" class");
 } else {
 } else {
-return _st(aClass)._name();
+$3=_st(aClass)._isNil();
+if(smalltalk.assert($3)){
+$1="nil";
+} else {
+$1=_st(aClass)._name();
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,$4);
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})},
 }, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass}, smalltalk.ChunkExporter)})},
 args: ["aClass"],
 args: ["aClass"],
@@ -562,16 +547,14 @@ category: 'not yet classified',
 fn: function (aClass,aStream){
 fn: function (aClass,aStream){
 var self=this;
 var self=this;
 var map;
 var map;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 map=_st((smalltalk.Dictionary || Dictionary))._new();
 map=_st((smalltalk.Dictionary || Dictionary))._new();
-$1=aClass;
-$2=(function(category,methods){
-return smalltalk.withContext(function($ctx2) {
$3=_st(category)._match_("^\x5c*");
-if(! smalltalk.assert($3)){
+_st(aClass)._protocolsDo_((function(category,methods){
+return smalltalk.withContext(function($ctx2) {
$1=_st(category)._match_("^\x5c*");
+if(! smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 return _st(map)._at_put_(category,methods);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})});
-_st($1)._protocolsDo_($2);
+}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
 _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
 return smalltalk.withContext(function($ctx2) {
return _st(a).__lt_eq(b);
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 }, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
@@ -615,22 +598,18 @@ category: 'not yet classified',
 fn: function (package_,aStream){
 fn: function (package_,aStream){
 var self=this;
 var self=this;
 var name,map;
 var name,map;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$5,$7,$6,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 name=_st(package_)._name();
 name=_st(package_)._name();
-$1=_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._classes());
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=[each,_st(each)._class()];
-$4=(function(aClass){
+_st(_st((smalltalk.Package || Package))._sortedClasses_(_st(_st((smalltalk.Smalltalk || 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) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 return smalltalk.withContext(function($ctx3) {
map=_st((smalltalk.Dictionary || Dictionary))._new();
 map;
 map;
-$5=aClass;
-$6=(function(category,methods){
-return smalltalk.withContext(function($ctx4) {
$7=_st(category)._match_(_st("^\x5c*").__comma(name));
-if(smalltalk.assert($7)){
+_st(aClass)._protocolsDo_((function(category,methods){
+return smalltalk.withContext(function($ctx4) {
$1=_st(category)._match_(_st("^\x5c*").__comma(name));
+if(smalltalk.assert($1)){
 return _st(map)._at_put_(category,methods);
 return _st(map)._at_put_(category,methods);
 };
 };
-}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})});
-_st($5)._protocolsDo_($6);
+}, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return _st(_st(_st(map)._keys())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
 return smalltalk.withContext(function($ctx4) {
return _st(a).__lt_eq(b);
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
 }, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx1)})})))._do_((function(category){
@@ -639,10 +618,8 @@ return smalltalk.withContext(function($ctx4) {
methods=_st(map)._at_(category);
 methods;
 methods;
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 return _st(self)._exportMethods_category_of_on_(methods,category,aClass,aStream);
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
 }, function($ctx4) {$ctx4.fillBlock({category:category,methods:methods},$ctx1)})}));
-}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})});
-return _st($3)._do_($4);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})},
 return self}, function($ctx1) {$ctx1.fill(self,"exportPackageExtensionsOf:on:",{package_:package_,aStream:aStream,name:name,map:map}, smalltalk.ChunkExporter)})},
 args: ["package", "aStream"],
 args: ["package", "aStream"],
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22We need to override this one too since we need to group\x0a\x09all methods in a given protocol under a leading methodsFor: chunk\x0a\x09for that class.\x22\x0a\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| name map |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass |\x0a\x09\x09\x09map := Dictionary new.\x0a\x09\x09\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09\x09\x09(category match: '^\x5c*', name) ifTrue: [ map at: category put: methods ]].\x0a\x09\x09\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09\x09\x09methods := map at: category.\x09\x0a\x09\x09\x09\x09self exportMethods: methods category: category of: aClass on: aStream ]]]",
 source: "exportPackageExtensionsOf: package on: aStream\x0a\x09\x22We need to override this one too since we need to group\x0a\x09all methods in a given protocol under a leading methodsFor: chunk\x0a\x09for that class.\x22\x0a\x0a\x09\x22Issue #143: sort protocol alphabetically\x22\x0a\x0a\x09| name map |\x0a\x09name := package name.\x0a\x09(Package sortedClasses: Smalltalk current classes) do: [:each |\x0a\x09\x09{each. each class} do: [:aClass |\x0a\x09\x09\x09map := Dictionary new.\x0a\x09\x09\x09aClass protocolsDo: [:category :methods | \x0a\x09\x09\x09\x09(category match: '^\x5c*', name) ifTrue: [ map at: category put: methods ]].\x0a\x09\x09\x09(map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |\x0a\x09\x09\x09\x09methods := map at: category.\x09\x0a\x09\x09\x09\x09self exportMethods: methods category: category of: aClass on: aStream ]]]",
@@ -729,33 +706,29 @@ category: 'fileIn',
 fn: function (aStream){
 fn: function (aStream){
 var self=this;
 var self=this;
 var chunk,result,parser,lastEmpty;
 var chunk,result,parser,lastEmpty;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$6,$5,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 parser=_st((smalltalk.ChunkParser || ChunkParser))._on_(aStream);
 lastEmpty=false;
 lastEmpty=false;
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 return smalltalk.withContext(function($ctx2) {
chunk=_st(parser)._nextChunk();
 chunk;
 chunk;
 return _st(chunk)._isNil();
 return _st(chunk)._isNil();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(chunk)._isEmpty();
-$4=(function(){
-return smalltalk.withContext(function($ctx3) {
lastEmpty=true;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(chunk)._isEmpty();
+if(smalltalk.assert($1)){
+lastEmpty=true;
 return lastEmpty;
 return lastEmpty;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-$5=(function(){
-return smalltalk.withContext(function($ctx3) {
result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
+} else {
+result=_st(_st((smalltalk.Compiler || Compiler))._new())._evaluateExpression_(chunk);
 result;
 result;
-$6=lastEmpty;
-if(smalltalk.assert($6)){
+$2=lastEmpty;
+if(smalltalk.assert($2)){
 lastEmpty=false;
 lastEmpty=false;
 lastEmpty;
 lastEmpty;
 return _st(result)._scanFrom_(parser);
 return _st(result)._scanFrom_(parser);
 };
 };
-}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})});
-return _st($3)._ifTrue_ifFalse_($4,$5);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileFalse_($2);
+};
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})},
 return self}, function($ctx1) {$ctx1.fill(self,"import:",{aStream:aStream,chunk:chunk,result:result,parser:parser,lastEmpty:lastEmpty}, smalltalk.Importer)})},
 args: ["aStream"],
 args: ["aStream"],
 source: "import: aStream\x0a    | chunk result parser lastEmpty |\x0a    parser := ChunkParser on: aStream.\x0a    lastEmpty := false.\x0a    [chunk := parser nextChunk.\x0a     chunk isNil] whileFalse: [\x0a        chunk isEmpty\x0a       \x09\x09ifTrue: [lastEmpty := true]\x0a       \x09\x09ifFalse: [\x0a        \x09\x09result := Compiler new evaluateExpression: chunk.\x0a        \x09\x09lastEmpty \x0a            \x09\x09\x09ifTrue: [\x0a                                  \x09lastEmpty := false.\x0a                                  \x09result scanFrom: parser]]]",
 source: "import: aStream\x0a    | chunk result parser lastEmpty |\x0a    parser := ChunkParser on: aStream.\x0a    lastEmpty := false.\x0a    [chunk := parser nextChunk.\x0a     chunk isNil] whileFalse: [\x0a        chunk isEmpty\x0a       \x09\x09ifTrue: [lastEmpty := true]\x0a       \x09\x09ifFalse: [\x0a        \x09\x09result := Compiler new evaluateExpression: chunk.\x0a        \x09\x09lastEmpty \x0a            \x09\x09\x09ifTrue: [\x0a                                  \x09lastEmpty := false.\x0a                                  \x09result scanFrom: parser]]]",
@@ -795,23 +768,16 @@ category: 'laoding',
 fn: function (packageName,aString){
 fn: function (packageName,aString){
 var self=this;
 var self=this;
 var url;
 var url;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$8,$7,$6,$3;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
 url=_st(_st(_st(_st("/").__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
-$1=jQuery;
-$2=url;
-$4=_st("type").__minus_gt("GET");
-$5=_st("dataType").__minus_gt("script");
-$7=(function(jqXHR,textStatus){
-return smalltalk.withContext(function($ctx2) {
$8=_st(_st(jqXHR)._readyState()).__eq((4));
-if(smalltalk.assert($8)){
+_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._fromPairs_([_st("type").__minus_gt("GET"),_st("dataType").__minus_gt("script"),_st("complete").__minus_gt((function(jqXHR,textStatus){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(jqXHR)._readyState()).__eq((4));
+if(smalltalk.assert($1)){
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 return _st(self)._initializePackageNamed_prefix_(packageName,aString);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})});
-$6=_st("complete").__minus_gt($7);
-$3=smalltalk.HashedCollection._fromPairs_([$4,$5,$6,_st("error").__minus_gt((function(){
+}, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),_st("error").__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
 return smalltalk.withContext(function($ctx2) {
return _st(window)._alert_(_st("Could not load package at:  ").__comma(url));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
-_st($1)._ajax_options_($2,$3);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})},
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url}, smalltalk.PackageLoader)})},
 args: ["packageName", "aString"],
 args: ["packageName", "aString"],
 source: "loadPackage: packageName prefix: aString\x09\x0a\x09| url |\x0a    url := '/', aString, '/js/', packageName, '.js'.\x0a\x09jQuery \x0a\x09\x09ajax: url\x0a        options: #{\x0a\x09\x09\x09'type' -> 'GET'.\x0a\x09\x09\x09'dataType' -> 'script'.\x0a    \x09\x09'complete' -> [ :jqXHR :textStatus | \x0a\x09\x09\x09\x09jqXHR readyState = 4 \x0a                \x09ifTrue: [ self initializePackageNamed: packageName prefix: aString ] ].\x0a\x09\x09\x09'error' -> [ window alert: 'Could not load package at:  ', url ]\x0a\x09\x09}",
 source: "loadPackage: packageName prefix: aString\x09\x0a\x09| url |\x0a    url := '/', aString, '/js/', packageName, '.js'.\x0a\x09jQuery \x0a\x09\x09ajax: url\x0a        options: #{\x0a\x09\x09\x09'type' -> 'GET'.\x0a\x09\x09\x09'dataType' -> 'script'.\x0a    \x09\x09'complete' -> [ :jqXHR :textStatus | \x0a\x09\x09\x09\x09jqXHR readyState = 4 \x0a                \x09ifTrue: [ self initializePackageNamed: packageName prefix: aString ] ].\x0a\x09\x09\x09'error' -> [ window alert: 'Could not load package at:  ', url ]\x0a\x09\x09}",

+ 28 - 25
js/Kernel-Classes.deploy.js

@@ -271,23 +271,21 @@ selector: "lookupSelector:",
 fn: function (selector){
 fn: function (selector){
 var self=this;
 var self=this;
 var lookupClass;
 var lookupClass;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 var $early={};
 var $early={};
 try {
 try {
 lookupClass=self;
 lookupClass=self;
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(lookupClass).__eq(nil);
 return smalltalk.withContext(function($ctx2) {
return _st(lookupClass).__eq(nil);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(lookupClass)._includesSelector_(selector);
-if(smalltalk.assert($3)){
-$4=_st(lookupClass)._methodAt_(selector);
-throw $early=[$4];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(lookupClass)._includesSelector_(selector);
+if(smalltalk.assert($1)){
+$2=_st(lookupClass)._methodAt_(selector);
+throw $early=[$2];
 };
 };
 lookupClass=_st(lookupClass)._superclass();
 lookupClass=_st(lookupClass)._superclass();
 return lookupClass;
 return lookupClass;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileFalse_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return nil;
 return nil;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -856,17 +854,22 @@ smalltalk.method({
 selector: "addSubclassOf:named:instanceVariableNames:package:",
 selector: "addSubclassOf:named:instanceVariableNames:package:",
 fn: function (aClass,aString,aCollection,packageName){
 fn: function (aClass,aString,aCollection,packageName){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
-$1=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
+var theClass;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+theClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
+$1=theClass;
 if(($receiver = $1) == nil || $receiver == undefined){
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 $1;
 } else {
 } else {
-$2=_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(aString,aClass,aCollection,packageName);
-return $2;
-};
-$3=_st(self)._basicAddSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
+$2=_st(_st(theClass)._superclass()).__eq_eq(aClass);
+if(! smalltalk.assert($2)){
+$3=_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(aString,aClass,aCollection,packageName);
 return $3;
 return $3;
-}, function($ctx1) {$ctx1.fill(self,"addSubclassOf:named:instanceVariableNames:package:",{aClass:aClass,aString:aString,aCollection:aCollection,packageName:packageName}, smalltalk.ClassBuilder)})}
+};
+};
+$4=_st(self)._basicAddSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
+return $4;
+}, function($ctx1) {$ctx1.fill(self,"addSubclassOf:named:instanceVariableNames:package:",{aClass:aClass,aString:aString,aCollection:aCollection,packageName:packageName,theClass:theClass}, smalltalk.ClassBuilder)})}
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
 
 
@@ -1026,7 +1029,8 @@ smalltalk.method({
 selector: "migrateClass:superclass:",
 selector: "migrateClass:superclass:",
 fn: function (aClass,anotherClass){
 fn: function (aClass,anotherClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(_st(aClass)._name(),anotherClass,_st(aClass)._instanceVariableNames(),_st(_st(aClass)._package())._name());
+return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(_st(aClass)._name());
+_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(_st(aClass)._name(),anotherClass,_st(aClass)._instanceVariableNames(),_st(_st(aClass)._package())._name());
 return self}, function($ctx1) {$ctx1.fill(self,"migrateClass:superclass:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})}
 return self}, function($ctx1) {$ctx1.fill(self,"migrateClass:superclass:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})}
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -1039,6 +1043,7 @@ fn: function (aString,aClass,aCollection,packageName){
 var self=this;
 var self=this;
 var oldClass,newClass;
 var oldClass,newClass;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+_st(console)._log_(_st("*** MIGRATING ").__comma(aString));
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
 _st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
 _st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
 newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
 newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
@@ -1250,19 +1255,17 @@ selector: "getNodesFrom:",
 fn: function (aCollection){
 fn: function (aCollection){
 var self=this;
 var self=this;
 var children,others;
 var children,others;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 children=[];
 children=[];
 others=[];
 others=[];
-$1=aCollection;
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._superclass()).__eq(_st(self)._theClass());
-if(smalltalk.assert($3)){
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._superclass()).__eq(_st(self)._theClass());
+if(smalltalk.assert($1)){
 return _st(children)._add_(each);
 return _st(children)._add_(each);
 } else {
 } else {
 return _st(others)._add_(each);
 return _st(others)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 self["@nodes"]=_st(children)._collect_((function(each){
 self["@nodes"]=_st(children)._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,_st(_st(self)._level()).__plus((1)));
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,_st(_st(self)._level()).__plus((1)));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));

+ 34 - 31
js/Kernel-Classes.js

@@ -363,23 +363,21 @@ category: 'accessing',
 fn: function (selector){
 fn: function (selector){
 var self=this;
 var self=this;
 var lookupClass;
 var lookupClass;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 var $early={};
 var $early={};
 try {
 try {
 lookupClass=self;
 lookupClass=self;
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(lookupClass).__eq(nil);
 return smalltalk.withContext(function($ctx2) {
return _st(lookupClass).__eq(nil);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(lookupClass)._includesSelector_(selector);
-if(smalltalk.assert($3)){
-$4=_st(lookupClass)._methodAt_(selector);
-throw $early=[$4];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._whileFalse_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(lookupClass)._includesSelector_(selector);
+if(smalltalk.assert($1)){
+$2=_st(lookupClass)._methodAt_(selector);
+throw $early=[$2];
 };
 };
 lookupClass=_st(lookupClass)._superclass();
 lookupClass=_st(lookupClass)._superclass();
 return lookupClass;
 return lookupClass;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._whileFalse_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return nil;
 return nil;
 }
 }
 catch(e) {if(e===$early)return e[0]; throw e}
 catch(e) {if(e===$early)return e[0]; throw e}
@@ -1151,20 +1149,25 @@ selector: "addSubclassOf:named:instanceVariableNames:package:",
 category: 'private',
 category: 'private',
 fn: function (aClass,aString,aCollection,packageName){
 fn: function (aClass,aString,aCollection,packageName){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
-$1=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
+var theClass;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+theClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
+$1=theClass;
 if(($receiver = $1) == nil || $receiver == undefined){
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
 $1;
 } else {
 } else {
-$2=_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(aString,aClass,aCollection,packageName);
-return $2;
-};
-$3=_st(self)._basicAddSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
+$2=_st(_st(theClass)._superclass()).__eq_eq(aClass);
+if(! smalltalk.assert($2)){
+$3=_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(aString,aClass,aCollection,packageName);
 return $3;
 return $3;
-}, function($ctx1) {$ctx1.fill(self,"addSubclassOf:named:instanceVariableNames:package:",{aClass:aClass,aString:aString,aCollection:aCollection,packageName:packageName}, smalltalk.ClassBuilder)})},
+};
+};
+$4=_st(self)._basicAddSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
+return $4;
+}, function($ctx1) {$ctx1.fill(self,"addSubclassOf:named:instanceVariableNames:package:",{aClass:aClass,aString:aString,aCollection:aCollection,packageName:packageName,theClass:theClass}, smalltalk.ClassBuilder)})},
 args: ["aClass", "aString", "aCollection", "packageName"],
 args: ["aClass", "aString", "aCollection", "packageName"],
-source: "addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName\x0a\x09\x0a    (Smalltalk current at: aString) ifNotNil: [ \x0a    \x09^ self \x0a        \x09migrateClassNamed: aString \x0a            superclass: aClass \x0a            instanceVariableNames: aCollection \x0a            package: packageName ].\x0a\x0a\x09^ self \x0a    \x09basicAddSubclassOf: aClass \x0a        named: aString \x0a        instanceVariableNames: aCollection \x0a        package: packageName",
-messageSends: ["ifNotNil:", "migrateClassNamed:superclass:instanceVariableNames:package:", "at:", "current", "basicAddSubclassOf:named:instanceVariableNames:package:"],
+source: "addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName\x0a    | theClass |\x0a    \x0a    theClass := Smalltalk current at: aString.\x0a    \x0a   \x09theClass ifNotNil: [ \x0a    \x09theClass superclass == aClass ifFalse: [\x0a    \x09\x09^ self \x0a        \x09\x09migrateClassNamed: aString \x0a           \x09 \x09superclass: aClass \x0a           \x09 \x09instanceVariableNames: aCollection \x0a            \x09package: packageName ] ].\x0a\x0a\x09^ self \x0a    \x09basicAddSubclassOf: aClass \x0a        named: aString \x0a        instanceVariableNames: aCollection \x0a        package: packageName",
+messageSends: ["at:", "current", "ifNotNil:", "ifFalse:", "migrateClassNamed:superclass:instanceVariableNames:package:", "==", "superclass", "basicAddSubclassOf:named:instanceVariableNames:package:"],
 referencedClasses: ["Smalltalk"]
 referencedClasses: ["Smalltalk"]
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -1376,11 +1379,12 @@ selector: "migrateClass:superclass:",
 category: 'private',
 category: 'private',
 fn: function (aClass,anotherClass){
 fn: function (aClass,anotherClass){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(_st(aClass)._name(),anotherClass,_st(aClass)._instanceVariableNames(),_st(_st(aClass)._package())._name());
+return smalltalk.withContext(function($ctx1) { 
_st(console)._log_(_st(aClass)._name());
+_st(self)._migrateClassNamed_superclass_instanceVariableNames_package_(_st(aClass)._name(),anotherClass,_st(aClass)._instanceVariableNames(),_st(_st(aClass)._package())._name());
 return self}, function($ctx1) {$ctx1.fill(self,"migrateClass:superclass:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})},
 return self}, function($ctx1) {$ctx1.fill(self,"migrateClass:superclass:",{aClass:aClass,anotherClass:anotherClass}, smalltalk.ClassBuilder)})},
 args: ["aClass", "anotherClass"],
 args: ["aClass", "anotherClass"],
-source: "migrateClass: aClass superclass: anotherClass\x0a\x09self \x0a    \x09migrateClassNamed: aClass name\x0a        superclass: anotherClass\x0a        instanceVariableNames: aClass instanceVariableNames\x0a        package: aClass package name",
-messageSends: ["migrateClassNamed:superclass:instanceVariableNames:package:", "name", "instanceVariableNames", "package"],
+source: "migrateClass: aClass superclass: anotherClass\x0a\x09console log: aClass name.\x0a\x09self \x0a    \x09migrateClassNamed: aClass name\x0a        superclass: anotherClass\x0a        instanceVariableNames: aClass instanceVariableNames\x0a        package: aClass package name",
+messageSends: ["log:", "name", "migrateClassNamed:superclass:instanceVariableNames:package:", "instanceVariableNames", "package"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -1394,6 +1398,7 @@ fn: function (aString,aClass,aCollection,packageName){
 var self=this;
 var self=this;
 var oldClass,newClass;
 var oldClass,newClass;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
 return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+_st(console)._log_(_st("*** MIGRATING ").__comma(aString));
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
 oldClass=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._at_(aString);
 _st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
 _st(self)._basicRenameClass_to_(oldClass,_st("Old").__comma(aString));
 newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
 newClass=_st(self)._addSubclassOf_named_instanceVariableNames_package_(aClass,aString,aCollection,packageName);
@@ -1414,8 +1419,8 @@ $3=newClass;
 return $3;
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass}, smalltalk.ClassBuilder)})},
 }, function($ctx1) {$ctx1.fill(self,"migrateClassNamed:superclass:instanceVariableNames:package:",{aString:aString,aClass:aClass,aCollection:aCollection,packageName:packageName,oldClass:oldClass,newClass:newClass}, smalltalk.ClassBuilder)})},
 args: ["aString", "aClass", "aCollection", "packageName"],
 args: ["aString", "aClass", "aCollection", "packageName"],
-source: "migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName\x0a\x09| oldClass newClass |\x0a    \x0a    oldClass := Smalltalk current at: aString.\x0a    \x0a    \x22Rename the old class for existing instances\x22\x0a\x09self basicRenameClass: oldClass to: 'Old', aString.\x0a    \x0a    newClass := self \x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: aString \x0a\x09\x09instanceVariableNames: aCollection\x0a\x09\x09package: packageName.\x0a\x0a\x09oldClass subclasses do: [ :each |\x0a    \x09self migrateClass: each superclass: newClass ].\x0a\x0a    [ self copyClass: oldClass to: newClass ] \x0a    \x09on: Error\x0a        do: [ :exception |\x0a        \x09self \x0a            \x09basicRemoveClass: newClass;\x0a            \x09basicRenameClass: oldClass to: aString.\x0a            exception signal ].\x0a            \x0a    self basicRemoveClass: oldClass.\x0a\x09^newClass",
-messageSends: ["at:", "current", "basicRenameClass:to:", ",", "addSubclassOf:named:instanceVariableNames:package:", "do:", "migrateClass:superclass:", "subclasses", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:"],
+source: "migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName\x0a\x09| oldClass newClass |\x0a    \x0a    console log: '*** MIGRATING ', aString.\x0a    \x0a    oldClass := Smalltalk current at: aString.\x0a    \x0a    \x22Rename the old class for existing instances\x22\x0a\x09self basicRenameClass: oldClass to: 'Old', aString.\x0a    \x0a    newClass := self \x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: aString \x0a\x09\x09instanceVariableNames: aCollection\x0a\x09\x09package: packageName.\x0a\x0a\x09oldClass subclasses do: [ :each |\x0a    \x09self migrateClass: each superclass: newClass ].\x0a\x0a    [ self copyClass: oldClass to: newClass ] \x0a    \x09on: Error\x0a        do: [ :exception |\x0a        \x09self \x0a            \x09basicRemoveClass: newClass;\x0a            \x09basicRenameClass: oldClass to: aString.\x0a            exception signal ].\x0a            \x0a    self basicRemoveClass: oldClass.\x0a\x09^newClass",
+messageSends: ["log:", ",", "at:", "current", "basicRenameClass:to:", "addSubclassOf:named:instanceVariableNames:package:", "do:", "migrateClass:superclass:", "subclasses", "on:do:", "basicRemoveClass:", "signal", "copyClass:to:"],
 referencedClasses: ["Smalltalk", "Error"]
 referencedClasses: ["Smalltalk", "Error"]
 }),
 }),
 smalltalk.ClassBuilder);
 smalltalk.ClassBuilder);
@@ -1672,19 +1677,17 @@ category: 'accessing',
 fn: function (aCollection){
 fn: function (aCollection){
 var self=this;
 var self=this;
 var children,others;
 var children,others;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1;
 children=[];
 children=[];
 others=[];
 others=[];
-$1=aCollection;
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(_st(each)._superclass()).__eq(_st(self)._theClass());
-if(smalltalk.assert($3)){
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(each)._superclass()).__eq(_st(self)._theClass());
+if(smalltalk.assert($1)){
 return _st(children)._add_(each);
 return _st(children)._add_(each);
 } else {
 } else {
 return _st(others)._add_(each);
 return _st(others)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 self["@nodes"]=_st(children)._collect_((function(each){
 self["@nodes"]=_st(children)._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,_st(_st(self)._level()).__plus((1)));
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,_st(_st(self)._level()).__plus((1)));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 144 - 152
js/Kernel-Collections.deploy.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 144 - 152
js/Kernel-Collections.js


+ 9 - 8
js/Kernel-Exceptions.deploy.js

@@ -357,17 +357,18 @@ smalltalk.method({
 selector: "logErrorContext:",
 selector: "logErrorContext:",
 fn: function (aContext){
 fn: function (aContext){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 $1=aContext;
 $1=aContext;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(aContext)._home();
-if(($receiver = $3) == nil || $receiver == undefined){
-return $3;
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+$2=_st(aContext)._home();
+if(($receiver = $2) == nil || $receiver == undefined){
+$2;
 } else {
 } else {
-return _st(self)._logContext_(_st(aContext)._home());
+_st(self)._logContext_(_st(aContext)._home());
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotNil_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})}
 return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})}
 }),
 }),
 smalltalk.ErrorHandler);
 smalltalk.ErrorHandler);

+ 9 - 8
js/Kernel-Exceptions.js

@@ -498,17 +498,18 @@ selector: "logErrorContext:",
 category: 'private',
 category: 'private',
 fn: function (aContext){
 fn: function (aContext){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 $1=aContext;
 $1=aContext;
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(aContext)._home();
-if(($receiver = $3) == nil || $receiver == undefined){
-return $3;
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+$2=_st(aContext)._home();
+if(($receiver = $2) == nil || $receiver == undefined){
+$2;
 } else {
 } else {
-return _st(self)._logContext_(_st(aContext)._home());
+_st(self)._logContext_(_st(aContext)._home());
+};
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ifNotNil_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})},
 return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext}, smalltalk.ErrorHandler)})},
 args: ["aContext"],
 args: ["aContext"],
 source: "logErrorContext: aContext\x0a\x09aContext ifNotNil: [\x0a\x09\x09aContext home ifNotNil: [\x0a\x09\x09\x09self logContext: aContext home]]",
 source: "logErrorContext: aContext\x0a\x09aContext ifNotNil: [\x0a\x09\x09aContext home ifNotNil: [\x0a\x09\x09\x09self logContext: aContext home]]",

+ 5 - 5
js/Kernel-Methods.js

@@ -1016,7 +1016,7 @@ smalltalk.Message.klass);
 
 
 
 
 smalltalk.addClass('MethodContext', smalltalk.Object, [], 'Kernel-Methods');
 smalltalk.addClass('MethodContext', smalltalk.Object, [], 'Kernel-Methods');
-smalltalk.MethodContext.comment="MethodContext holds all the dynamic state associated with the execution of either a method activation resulting from a message send. That is used to build the call stack while debugging.\x0a  \x0aMethodContext instances are JavaScript `SmalltalkMethodContext` objects defined in boot.js "
+smalltalk.MethodContext.comment="MethodContext holds all the dynamic state associated with the execution of either a method activation resulting from a message send. That is used to build the call stack while debugging.\x0a  \x0aMethodContext instances are JavaScript `SmalltalkMethodContext` objects defined in boot.js"
 smalltalk.addMethod(
 smalltalk.addMethod(
 "_asString",
 "_asString",
 smalltalk.method({
 smalltalk.method({
@@ -1256,7 +1256,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:",{aString:aString}, smalltalk.NativeFunction.klass)})},
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:",{aString:aString}, smalltalk.NativeFunction.klass)})},
 args: ["aString"],
 args: ["aString"],
-source: "constructor: aString\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native();\x0a\x09>\x0a",
+source: "constructor: aString\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native();\x0a\x09>",
 messageSends: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -1275,7 +1275,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:",{aString:aString,anObject:anObject}, smalltalk.NativeFunction.klass)})},
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:",{aString:aString,anObject:anObject}, smalltalk.NativeFunction.klass)})},
 args: ["aString", "anObject"],
 args: ["aString", "anObject"],
-source: "constructor: aString value:anObject\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject);\x0a\x09>\x0a",
+source: "constructor: aString value:anObject\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject);\x0a\x09>",
 messageSends: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -1294,7 +1294,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2}, smalltalk.NativeFunction.klass)})},
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2}, smalltalk.NativeFunction.klass)})},
 args: ["aString", "anObject", "anObject2"],
 args: ["aString", "anObject", "anObject2"],
-source: "constructor: aString value:anObject value: anObject2\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject,anObject2);\x0a\x09>\x0a",
+source: "constructor: aString value:anObject value: anObject2\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject,anObject2);\x0a\x09>",
 messageSends: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -1313,7 +1313,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2,anObject3:anObject3}, smalltalk.NativeFunction.klass)})},
 return self}, function($ctx1) {$ctx1.fill(self,"constructor:value:value:value:",{aString:aString,anObject:anObject,anObject2:anObject2,anObject3:anObject3}, smalltalk.NativeFunction.klass)})},
 args: ["aString", "anObject", "anObject2", "anObject3"],
 args: ["aString", "anObject", "anObject2", "anObject3"],
-source: "constructor: aString value:anObject value: anObject2 value:anObject3\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject,anObject2, anObject3);\x0a\x09>\x0a",
+source: "constructor: aString value:anObject value: anObject2 value:anObject3\x0a\x09<\x0a    \x09var native=eval(aString); \x0a        return new native(anObject,anObject2, anObject3);\x0a\x09>",
 messageSends: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),

+ 12 - 16
js/Kernel-Objects.deploy.js

@@ -2724,19 +2724,17 @@ selector: "sortedClasses:",
 fn: function (classes){
 fn: function (classes){
 var self=this;
 var self=this;
 var children,others,nodes,expandedClasses;
 var children,others,nodes,expandedClasses;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 children=[];
 children=[];
 others=[];
 others=[];
-$1=classes;
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(classes)._includes_(_st(each)._superclass());
-if(smalltalk.assert($3)){
+_st(classes)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(classes)._includes_(_st(each)._superclass());
+if(smalltalk.assert($1)){
 return _st(others)._add_(each);
 return _st(others)._add_(each);
 } else {
 } else {
 return _st(children)._add_(each);
 return _st(children)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 nodes=_st(children)._collect_((function(each){
 nodes=_st(children)._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,(0));
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,(0));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
@@ -2747,8 +2745,8 @@ expandedClasses=_st((smalltalk.Array || Array))._new();
 _st(nodes)._do_((function(aNode){
 _st(nodes)._do_((function(aNode){
 return smalltalk.withContext(function($ctx2) {
return _st(aNode)._traverseClassesWith_(expandedClasses);
 return smalltalk.withContext(function($ctx2) {
return _st(aNode)._traverseClassesWith_(expandedClasses);
 }, function($ctx2) {$ctx2.fillBlock({aNode:aNode},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({aNode:aNode},$ctx1)})}));
-$4=expandedClasses;
-return $4;
+$2=expandedClasses;
+return $2;
 }, function($ctx1) {$ctx1.fill(self,"sortedClasses:",{classes:classes,children:children,others:others,nodes:nodes,expandedClasses:expandedClasses}, smalltalk.Package.klass)})}
 }, function($ctx1) {$ctx1.fill(self,"sortedClasses:",{classes:classes,children:children,others:others,nodes:nodes,expandedClasses:expandedClasses}, smalltalk.Package.klass)})}
 }),
 }),
 smalltalk.Package.klass);
 smalltalk.Package.klass);
@@ -2841,19 +2839,17 @@ smalltalk.method({
 selector: "printString",
 selector: "printString",
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
-$2=(smalltalk.String || String);
-$3=(function(stream){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
_st(stream)._nextPutAll_(_st(_st(self["@x"])._printString()).__comma("@"));
 return smalltalk.withContext(function($ctx2) {
_st(stream)._nextPutAll_(_st(_st(self["@x"])._printString()).__comma("@"));
-$4=_st(_st(self["@y"])._notNil())._and_((function(){
+$2=_st(_st(self["@y"])._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(self["@y"])._negative();
 return smalltalk.withContext(function($ctx3) {
return _st(self["@y"])._negative();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($4)){
+if(smalltalk.assert($2)){
 _st(stream)._space();
 _st(stream)._space();
 };
 };
 return _st(stream)._nextPutAll_(_st(self["@y"])._printString());
 return _st(stream)._nextPutAll_(_st(self["@y"])._printString());
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})});
-$1=_st($2)._streamContents_($3);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"printString",{}, smalltalk.Point)})}
 }, function($ctx1) {$ctx1.fill(self,"printString",{}, smalltalk.Point)})}
 }),
 }),

+ 12 - 16
js/Kernel-Objects.js

@@ -3766,19 +3766,17 @@ category: 'sorting',
 fn: function (classes){
 fn: function (classes){
 var self=this;
 var self=this;
 var children,others,nodes,expandedClasses;
 var children,others,nodes,expandedClasses;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 children=[];
 children=[];
 others=[];
 others=[];
-$1=classes;
-$2=(function(each){
-return smalltalk.withContext(function($ctx2) {
$3=_st(classes)._includes_(_st(each)._superclass());
-if(smalltalk.assert($3)){
+_st(classes)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(classes)._includes_(_st(each)._superclass());
+if(smalltalk.assert($1)){
 return _st(others)._add_(each);
 return _st(others)._add_(each);
 } else {
 } else {
 return _st(children)._add_(each);
 return _st(children)._add_(each);
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})});
-_st($1)._do_($2);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 nodes=_st(children)._collect_((function(each){
 nodes=_st(children)._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,(0));
 return smalltalk.withContext(function($ctx2) {
return _st((smalltalk.ClassSorterNode || ClassSorterNode))._on_classes_level_(each,others,(0));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
@@ -3789,8 +3787,8 @@ expandedClasses=_st((smalltalk.Array || Array))._new();
 _st(nodes)._do_((function(aNode){
 _st(nodes)._do_((function(aNode){
 return smalltalk.withContext(function($ctx2) {
return _st(aNode)._traverseClassesWith_(expandedClasses);
 return smalltalk.withContext(function($ctx2) {
return _st(aNode)._traverseClassesWith_(expandedClasses);
 }, function($ctx2) {$ctx2.fillBlock({aNode:aNode},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({aNode:aNode},$ctx1)})}));
-$4=expandedClasses;
-return $4;
+$2=expandedClasses;
+return $2;
 }, function($ctx1) {$ctx1.fill(self,"sortedClasses:",{classes:classes,children:children,others:others,nodes:nodes,expandedClasses:expandedClasses}, smalltalk.Package.klass)})},
 }, function($ctx1) {$ctx1.fill(self,"sortedClasses:",{classes:classes,children:children,others:others,nodes:nodes,expandedClasses:expandedClasses}, smalltalk.Package.klass)})},
 args: ["classes"],
 args: ["classes"],
 source: "sortedClasses: classes\x0a\x09\x22Answer classes, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)\x22\x0a\x0a\x09| children others nodes expandedClasses |\x0a\x09children := #().\x0a\x09others := #().\x0a\x09classes do: [:each |\x0a\x09\x09(classes includes: each superclass)\x0a\x09\x09\x09ifFalse: [children add: each]\x0a\x09\x09\x09ifTrue: [others add: each]].\x0a\x09nodes := children collect: [:each |\x0a\x09\x09ClassSorterNode on: each classes: others level: 0].\x0a\x09nodes := nodes sorted: [:a :b | a theClass name <= b theClass name ].\x0a\x09expandedClasses := Array new.\x0a\x09nodes do: [:aNode |\x0a\x09\x09aNode traverseClassesWith: expandedClasses].\x0a\x09^expandedClasses",
 source: "sortedClasses: classes\x0a\x09\x22Answer classes, sorted by superclass/subclasses and by class name for common subclasses (Issue #143)\x22\x0a\x0a\x09| children others nodes expandedClasses |\x0a\x09children := #().\x0a\x09others := #().\x0a\x09classes do: [:each |\x0a\x09\x09(classes includes: each superclass)\x0a\x09\x09\x09ifFalse: [children add: each]\x0a\x09\x09\x09ifTrue: [others add: each]].\x0a\x09nodes := children collect: [:each |\x0a\x09\x09ClassSorterNode on: each classes: others level: 0].\x0a\x09nodes := nodes sorted: [:a :b | a theClass name <= b theClass name ].\x0a\x09expandedClasses := Array new.\x0a\x09nodes do: [:aNode |\x0a\x09\x09aNode traverseClassesWith: expandedClasses].\x0a\x09^expandedClasses",
@@ -3919,19 +3917,17 @@ selector: "printString",
 category: 'printing',
 category: 'printing',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
-$2=(smalltalk.String || String);
-$3=(function(stream){
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$1=_st((smalltalk.String || String))._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
_st(stream)._nextPutAll_(_st(_st(self["@x"])._printString()).__comma("@"));
 return smalltalk.withContext(function($ctx2) {
_st(stream)._nextPutAll_(_st(_st(self["@x"])._printString()).__comma("@"));
-$4=_st(_st(self["@y"])._notNil())._and_((function(){
+$2=_st(_st(self["@y"])._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(self["@y"])._negative();
 return smalltalk.withContext(function($ctx3) {
return _st(self["@y"])._negative();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($4)){
+if(smalltalk.assert($2)){
 _st(stream)._space();
 _st(stream)._space();
 };
 };
 return _st(stream)._nextPutAll_(_st(self["@y"])._printString());
 return _st(stream)._nextPutAll_(_st(self["@y"])._printString());
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})});
-$1=_st($2)._streamContents_($3);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"printString",{}, smalltalk.Point)})},
 }, function($ctx1) {$ctx1.fill(self,"printString",{}, smalltalk.Point)})},
 args: [],
 args: [],

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 122 - 125
js/Kernel-Tests.js


+ 23 - 28
js/SUnit.deploy.js

@@ -408,29 +408,27 @@ selector: "execute:",
 fn: function (aBlock){
 fn: function (aBlock){
 var self=this;
 var self=this;
 var failed;
 var failed;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 _st(self["@testCase"])._context_(self);
 _st(self["@testCase"])._context_(self);
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
failed=true;
 return smalltalk.withContext(function($ctx2) {
failed=true;
 failed;
 failed;
 _st(aBlock)._value();
 _st(aBlock)._value();
 failed=false;
 failed=false;
 return failed;
 return failed;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
 return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
-$3=_st(failed)._and_((function(){
+$1=_st(failed)._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
 return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($3)){
+if(smalltalk.assert($1)){
 _st(self["@testCase"])._finished();
 _st(self["@testCase"])._finished();
 };
 };
-$4=_st(self["@testCase"])._isAsync();
-if(! smalltalk.assert($4)){
+$2=_st(self["@testCase"])._isAsync();
+if(! smalltalk.assert($2)){
 return _st(self["@testCase"])._tearDown();
 return _st(self["@testCase"])._tearDown();
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ensure_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})}
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})}
 }),
 }),
 smalltalk.TestContext);
 smalltalk.TestContext);
@@ -485,20 +483,18 @@ smalltalk.method({
 selector: "execute:",
 selector: "execute:",
 fn: function (aBlock){
 fn: function (aBlock){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
-$1=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
 return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(self["@testCase"])._isAsync();
-if(! smalltalk.assert($3)){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(self["@testCase"])._isAsync();
+if(! smalltalk.assert($1)){
 _st(self["@result"])._increaseRuns();
 _st(self["@result"])._increaseRuns();
 return _st(self["@finished"])._value();
 return _st(self["@finished"])._value();
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ensure_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})}
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})}
 }),
 }),
 smalltalk.ReportingTestContext);
 smalltalk.ReportingTestContext);
@@ -695,19 +691,18 @@ smalltalk.method({
 selector: "status",
 selector: "status",
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(_st(self)._errors())._isEmpty();
 $2=_st(_st(self)._errors())._isEmpty();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(_st(self)._failures())._isEmpty();
-if(smalltalk.assert($4)){
-return "success";
+if(smalltalk.assert($2)){
+$3=_st(_st(self)._failures())._isEmpty();
+if(smalltalk.assert($3)){
+$1="success";
 } else {
 } else {
-return "failure";
+$1="failure";
+};
+} else {
+$1="error";
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,(function(){
-return smalltalk.withContext(function($ctx2) {
return "error";
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})}
 }, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})}
 }),
 }),

+ 24 - 29
js/SUnit.js

@@ -556,29 +556,27 @@ category: 'running',
 fn: function (aBlock){
 fn: function (aBlock){
 var self=this;
 var self=this;
 var failed;
 var failed;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$4,$2;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
 _st(self["@testCase"])._context_(self);
 _st(self["@testCase"])._context_(self);
-$1=(function(){
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
failed=true;
 return smalltalk.withContext(function($ctx2) {
failed=true;
 failed;
 failed;
 _st(aBlock)._value();
 _st(aBlock)._value();
 failed=false;
 failed=false;
 return failed;
 return failed;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
 return smalltalk.withContext(function($ctx2) {
_st(self["@testCase"])._context_(nil);
-$3=_st(failed)._and_((function(){
+$1=_st(failed)._and_((function(){
 return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
 return smalltalk.withContext(function($ctx3) {
return _st(self["@testCase"])._isAsync();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-if(smalltalk.assert($3)){
+if(smalltalk.assert($1)){
 _st(self["@testCase"])._finished();
 _st(self["@testCase"])._finished();
 };
 };
-$4=_st(self["@testCase"])._isAsync();
-if(! smalltalk.assert($4)){
+$2=_st(self["@testCase"])._isAsync();
+if(! smalltalk.assert($2)){
 return _st(self["@testCase"])._tearDown();
 return _st(self["@testCase"])._tearDown();
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ensure_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})},
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock,failed:failed}, smalltalk.TestContext)})},
 args: ["aBlock"],
 args: ["aBlock"],
 source: "execute: aBlock\x0a\x09| failed |\x0a    \x0a    testCase context: self.\x0a    [ \x0a    \x09failed := true. \x0a        aBlock value. \x0a        failed := false \x0a\x09] \x0a    \x09ensure: [\x0a        \x09testCase context: nil.\x0a            \x0a        \x09(failed and: [ testCase isAsync ]) ifTrue: [ \x0a            \x09testCase finished ].\x0a        \x09testCase isAsync ifFalse: [ \x0a        \x09\x09testCase tearDown ] ]",
 source: "execute: aBlock\x0a\x09| failed |\x0a    \x0a    testCase context: self.\x0a    [ \x0a    \x09failed := true. \x0a        aBlock value. \x0a        failed := false \x0a\x09] \x0a    \x09ensure: [\x0a        \x09testCase context: nil.\x0a            \x0a        \x09(failed and: [ testCase isAsync ]) ifTrue: [ \x0a            \x09testCase finished ].\x0a        \x09testCase isAsync ifFalse: [ \x0a        \x09\x09testCase tearDown ] ]",
@@ -654,20 +652,18 @@ selector: "execute:",
 category: 'running',
 category: 'running',
 fn: function (aBlock){
 fn: function (aBlock){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$3,$2;
-$1=(function(){
+return smalltalk.withContext(function($ctx1) { 
var $1;
+_st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
 return smalltalk.withContext(function($ctx3) {
return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$2=(function(){
-return smalltalk.withContext(function($ctx2) {
$3=_st(self["@testCase"])._isAsync();
-if(! smalltalk.assert($3)){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+return smalltalk.withContext(function($ctx2) {
$1=_st(self["@testCase"])._isAsync();
+if(! smalltalk.assert($1)){
 _st(self["@result"])._increaseRuns();
 _st(self["@result"])._increaseRuns();
 return _st(self["@finished"])._value();
 return _st(self["@finished"])._value();
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-_st($1)._ensure_($2);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})},
 return self}, function($ctx1) {$ctx1.fill(self,"execute:",{aBlock:aBlock}, smalltalk.ReportingTestContext)})},
 args: ["aBlock"],
 args: ["aBlock"],
 source: "execute: aBlock\x0a    [ \x0a    \x09self withErrorReporting: [ super execute: aBlock ] \x0a\x09]\x0a    \x09ensure: [ \x0a        \x09testCase isAsync ifFalse: [ \x0a            \x09result increaseRuns. finished value ] ]",
 source: "execute: aBlock\x0a    [ \x0a    \x09self withErrorReporting: [ super execute: aBlock ] \x0a\x09]\x0a    \x09ensure: [ \x0a        \x09testCase isAsync ifFalse: [ \x0a            \x09result increaseRuns. finished value ] ]",
@@ -905,7 +901,7 @@ return smalltalk.withContext(function($ctx2) {
return _st(self)._addError_(aTest
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"runCase:",{aTestCase:aTestCase}, smalltalk.TestResult)})},
 return self}, function($ctx1) {$ctx1.fill(self,"runCase:",{aTestCase:aTestCase}, smalltalk.TestResult)})},
 args: ["aTestCase"],
 args: ["aTestCase"],
-source: "runCase: aTestCase\x0a\x09[[\x09self increaseRuns.\x0a    \x09aTestCase runCase]\x0a\x09on: TestFailure do: [:ex | self addFailure: aTestCase]]\x0a\x09on: Error do: [:ex | self addError: aTestCase]\x0a",
+source: "runCase: aTestCase\x0a\x09[[\x09self increaseRuns.\x0a    \x09aTestCase runCase]\x0a\x09on: TestFailure do: [:ex | self addFailure: aTestCase]]\x0a\x09on: Error do: [:ex | self addError: aTestCase]",
 messageSends: ["on:do:", "addError:", "addFailure:", "increaseRuns", "runCase"],
 messageSends: ["on:do:", "addError:", "addFailure:", "increaseRuns", "runCase"],
 referencedClasses: ["Error", "TestFailure"]
 referencedClasses: ["Error", "TestFailure"]
 }),
 }),
@@ -936,19 +932,18 @@ selector: "status",
 category: 'accessing',
 category: 'accessing',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$4,$3,$1;
+return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(_st(self)._errors())._isEmpty();
 $2=_st(_st(self)._errors())._isEmpty();
-$3=(function(){
-return smalltalk.withContext(function($ctx2) {
$4=_st(_st(self)._failures())._isEmpty();
-if(smalltalk.assert($4)){
-return "success";
+if(smalltalk.assert($2)){
+$3=_st(_st(self)._failures())._isEmpty();
+if(smalltalk.assert($3)){
+$1="success";
 } else {
 } else {
-return "failure";
+$1="failure";
+};
+} else {
+$1="error";
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
-$1=_st($2)._ifTrue_ifFalse_($3,(function(){
-return smalltalk.withContext(function($ctx2) {
return "error";
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})},
 }, function($ctx1) {$ctx1.fill(self,"status",{}, smalltalk.TestResult)})},
 args: [],
 args: [],

+ 6 - 1
st/Canvas.st

@@ -629,7 +629,8 @@ ensureCurrent
 
 
 initialize
 initialize
 	super initialize.
 	super initialize.
-	self ensureCurrent
+    self isDOMAvailable ifTrue: [
+		self ensureCurrent ]
 ! !
 ! !
 
 
 !HTMLSnippet class methodsFor: 'instance creation'!
 !HTMLSnippet class methodsFor: 'instance creation'!
@@ -638,6 +639,10 @@ current
 	^ current
 	^ current
 !
 !
 
 
+isDOMAvailable
+	< return typeof document !!== 'undefined' >
+!
+
 new
 new
 	self shouldNotImplement
 	self shouldNotImplement
 ! !
 ! !

+ 5 - 1
st/Compiler-Exceptions.st

@@ -99,8 +99,12 @@ As a result Smalltalk errors are not swallowd by the Amber runtime and compilati
 
 
 !RethrowErrorHandler methodsFor: 'error handling'!
 !RethrowErrorHandler methodsFor: 'error handling'!
 
 
+basicSignal: anError
+	<throw anError>
+!
+
 handleError: anError
 handleError: anError
 	super handleError: anError.
 	super handleError: anError.
-    <throw anError>
+    self basicSignal: anError
 ! !
 ! !
 
 

+ 1 - 1
st/Compiler-Semantic.st

@@ -422,7 +422,7 @@ errorUnknownVariable: aNode
 	| identifier |
 	| identifier |
     identifier := aNode value.
     identifier := aNode value.
     
     
-	((#('jQuery' 'window' 'process' 'global') includes: identifier) not 
+	((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not 
         and: [ self isVariableGloballyUndefined: identifier ]) 
         and: [ self isVariableGloballyUndefined: identifier ]) 
         	ifTrue: [
         	ifTrue: [
 				UnknownVariableError new
 				UnknownVariableError new

+ 451 - 451
st/Documentation.st

@@ -1,231 +1,53 @@
 Smalltalk current createPackage: 'Documentation' properties: #{}!
 Smalltalk current createPackage: 'Documentation' properties: #{}!
-Object subclass: #DocumentationBuilder
-	instanceVariableNames: 'chapters announcer widget'
-	category: 'Documentation'!
-
-!DocumentationBuilder methodsFor: 'accessing'!
-
-chapters
-	^chapters ifNil: [chapters := self buildChapters]
-!
-
-announcer
-	^announcer ifNil: [announcer := Announcer new]
-!
-
-widget
-	^widget ifNil: [widget := DocumentationWidget on: self]
-! !
-
-!DocumentationBuilder methodsFor: 'building'!
-
-buildChapters
-	^((self class methodDictionary values sorted: [:a :b | a selector < b selector])
-		select: [:each | each category = 'chapters'])
-		collect: [:each | self perform: each selector]
-!
+Object subclass: #ChapterSelectionAnnouncement
+	instanceVariableNames: 'id'
+	package: 'Documentation'!
 
 
-buildOn: aCanvas
-	aCanvas with: self widget.
-	self 
-		checkHashChange;
-		checkHash
-!
+!ChapterSelectionAnnouncement methodsFor: 'accessing'!
 
 
-buildOnJQuery: aJQuery
-	self buildOn: (HTMLCanvas onJQuery: aJQuery)
+id
+	^id
 !
 !
 
 
-build
-	self buildOnJQuery: ('body' asJQuery)
+id: aString
+	id := aString
 ! !
 ! !
 
 
-!DocumentationBuilder methodsFor: 'chapters'!
-
-ch1introduction
-	^DocChapter new
-		title: 'Introduction';
-		contents: '
-
-##Amber Smalltalk in a nutshell
-
-Amber is an implementation of the Smalltalk-80 language. It is designed to make client-side web development **faster, easier and more fun** as it allows developers to write HTML5 applications in a live Smalltalk environment!!
-
-Amber is written in itself, including the IDE and the compiler and it runs **directly inside your browser**. The IDE is fairly complete with a class browser, workspace, transcript, unit test runner, object inspectors, cross reference tools and even a debugger.
-
-Noteworthy features:
-
-- Amber is semantically and syntactically very close to [Pharo Smalltalk](http://www.pharo-project.org). Pharo is considered the reference implementation.
-- Amber **seamlessly interacts with JavaScript** and can use its full eco system of libraries without any glue code needed.
-- Amber **has no dependencies** and can be used in any JavaScript runtime, not only inside browsers. An important example is [Node.js](http://nodejs.org).
-- Amber is a live Smalltalk that **compiles incrementally into efficient JavaScript** often mapping one-to-one with JavaScript equivalents.
-- Amber has a **Seaside influenced canvas library** to dynamically generate HTML.
-
-## Arguments for using Amber
-In our humble opinion the main arguments for using Amber are:
-
-- JavaScript is quite a broken language with lots of traps and odd quirks. It is the assembler of the Internet which is cool, but we don''t want to write in it.
-- Smalltalk as a language is immensely cleaner and more mature, both syntactically and semantically.
-- Smalltalk has a simple class model with a lightweight syntax for closures, it is in many ways a perfect match for the Good Parts of JavaScript.
-- Having a true live interactive incremental development environment where you can build your application directly in the browser is unbeatable.
-
-## Disclaimer
-
-This documentation doesn''t aim to teach Smalltalk. 
-Knowledge of Smalltalk is needed to understand the topics covered in this documentation. 
-If you want to learn the Smalltalk language, you can read the excellent [Pharo By Example](http://www.pharobyexample.org) book.
-'
-!
-
-ch2differencesWithOtherSmalltalks
-	^DocChapter new
-		title: 'Differences with other Smalltalks';
-		contents: '
-Amber has some differences with other Smalltalk implementations. This makes porting code a non-trivial thing, but still quite manageable.
-Because it maps Smalltalk constructs one-to-one with the JavaScript equivalent, including Smalltalk classes to JavaScript constructors, the core class library is simplified compared to Pharo Smalltalk.
-And since we want Amber to be useful in building lean browser apps we can''t let it bloat too much.
-
-But apart from missing things other Smalltalks may have, there are also things that are plain different:
-
-- The collection class hierarchy is much simpler compared to most Smalltalk implementations. In part this is because we want to map reasonably well with JavaScript counter parts.
-- As of today, there is no SortedCollection. The size of arrays is dynamic, and they behave like an ordered collection. They can also be sorted with the `#sort*` methods.
-- The `Date` class behaves like the `Date` and `TimeStamp` classes in Pharo Smalltalk. Therefore both `Date today` and `Date now` are valid in Amber.
-- Amber does not have class Character, but `String` does implement some of Character behavior so a single character String can work as a Character.
-- Amber does support **class instance variables**, but not class variables.
-- Amber only has global classes and packages, but not arbitrary objects. Use classes instead like `Smalltalk current` instead of `Smalltalk` etc.
-- Amber does not support pool dictionaries.
-- Amber uses **< ...javascript code... >** to inline JavaScript code and does not have pragmas.
-- Amber does not have class categories. The left side in the browser lists real Packages, but they feel much the same.
-'
-!
-
-ch3GettingStarted
-	^DocChapter new
-		title: 'Getting started';
-		contents: '
-To get started hacking in Amber you can basically take three routes, independent of your platform:
-
-1. Just **try it out directly** at [www.amber-lang.net](http://www.amber-lang.net) - click the **Class browser** button there. But you will **not be able to save any code you write**!! 
-    Still, it works fine for looking at the IDE and playing around. Just **don''t press F5/reload** - it will lose any code you have written.
-2. Download an Amber zip-ball, install [Nodejs](http://www.nodejs.org), fire up the Amber server and then open Amber from localhost - then you **can save code**. Detailed instructions are below!!
-3. Same as above but install git first and get a proper clone from [http://github.com/NicolasPetton/amber](http://github.com/NicolasPetton/amber) instead of a zip/tar-ball. 
-    If you want to **contribute to Amber itself** this is really what you want to do. In fact, in most cases this is what you want to do. It requires installing git first, but it is quite simple - although we leave this bit as an "exercise to the reader" :)
-
-**PLEASE NOTE:** Amber core developers use Linux. 
-We do not want to introduce dependencies that aren''t cross platform - but currently amberc (the command line compiler) is a bash script and we also use Makefiles 
-(for building Amber itself and server side examples) written on Linux/Unix. So using Windows is currently a bit limited - you can''t run "make" in the .st directory to rebuild whole of Amber for example.
- BUT... if you only want to use Amber to build web client apps and not really get involved in hacking Amber itself - then you should be fine!!
-
-## Downloading Amber
-Currently you can download in zip or tar-ball format, either cutting edge or a release. [Downloads are available here](https://github.com/NicolasPetton/amber/archives/amber). 
-
-Unpack wherever you like, but I would rename the directory that is unpacked to something slightly shorter - like say "amber". :)
-And yes, at this point you can double click the index.html file in the amber directory to get the IDE up, but again, **you will not be able to save code**. So please continue below :)
-
-## Installing Node.js
-[Node](http://www.nodejs.org) (for short) is simply the V8 Javascript VM from Google (used in Chrome) hooked together with some hard core C-libraries for doing "evented I/O".
-Basically it''s JavaScript for the server - on asynch steroids. Amber runs fine in Node and we use it for several Amber tools, like amberc (the command line Amber compiler) or the Amber server (see below). 
-There are also several Amber-Node examples to look at if you want to play with running Amber programs server side. **In short - you really want to install Nodejs. :)**
-
-- Installing Node on Linux can be done using your package tool of choice (`apt-get install nodejs` for example) or any other way described at [the download page](http://nodejs.org/#download).
-- Installing Node on MacOS or Windows is probably done best by using the [installers available at Nodejs.org](http://nodejs.org/#download).
-
-## Starting Amber server
-Nicolas has written a minimal webDAV server that is the easiest way to get up and running Amber with the ability to save code. This little server is written in... Amber!! 
-And it runs on top of Node. So to start it up serving your brand new directory tree of sweet Amber you do:
-
-	cd amber	(or whatever you called the directory you unpackaged)
-	./bin/server	(in windows you type `node server\server.js` instead)
-
-It should say it is listening on port 4000. If it does, hooray!! That means both Node and Amber are good. In Windows you might get a question about opening that port in the local firewall - yep, do it!!
-
-## Firing up Amber
-The Amber IDE is written in... Amber. It uses [jQuery](http://jquery.com) and runs right in your browser as a ... well, a web page. 
-We could open it up just using a file url - but the reason we performed the previous steps is so that we can load the IDE web page from a server that can handle PUTs (webDAV) of source code. 
-According to web security Amber can only do PUT back to the same server it was loaded from. Thus we instead want to open it [through our little server now listening on port 4000](http://localhost:4000/index.html).
-Clicking that link and then pressing the **Class browser** should get your Amber IDE running with the ability to commit modified packages locally.
-
-To verify that you can indeed commit now - just select a Package in the browser, like say "Examples" and press the **Commit** button below. **If all goes well nothing happens :)**. 
-So in order to really know if it worked we can check the modified date on the files **amber/st/Examples.st**, **amber/js/Examples.js** and **amber/js/Examples.deploy.js** - they should be brand new.
-
-NOTE: We can use any webDAV server and Apache2 has been used earlier and works fine. But the Amber server is smaller and simpler to start.
-'
-!
-
-ch5Index
-	^ClassesIndexChapter new
-!
-
-ch6KernelObjects
-	^PackageDocChapter on: (Package named: 'Kernel-Objects')
-!
-
-ch7KernelClasses
-	^PackageDocChapter on: (Package named: 'Kernel-Classes')
-!
-
-ch4Tutorials
-	^TutorialsChapter new
-!
-
-ch8KernelCollection
-	^PackageDocChapter on: (Package named: 'Kernel-Collections')
-!
-
-ch9KernelMethods
-	^PackageDocChapter on: (Package named: 'Kernel-Methods')
-! !
+Object subclass: #ClassSelectionAnnouncement
+	instanceVariableNames: 'theClass'
+	package: 'Documentation'!
 
 
-!DocumentationBuilder methodsFor: 'routing'!
+!ClassSelectionAnnouncement methodsFor: 'accessing'!
 
 
-checkHashChange
-	(window jQuery: window) bind: 'hashchange' do: [self checkHash]
+theClass
+	^theClass
 !
 !
 
 
-checkHash
-	| hash presentation |
-	hash := document location hash  replace: '^#' with: ''.
-	self announcer announce: (ChapterSelectionAnnouncement new 
-		id: hash; 
-		yourself)
-! !
-
-!DocumentationBuilder methodsFor: 'updating'!
-
-update
-	chapters := nil.
-	announcer := nil.
-	widget := nil.
-	(window jQuery: '.documentation') remove.
-	self build
-! !
-
-DocumentationBuilder class instanceVariableNames: 'current'!
-
-!DocumentationBuilder class methodsFor: 'accessing'!
-
-current
-	^current ifNil: [current := self new]
+theClass: aClass
+	theClass := aClass
 ! !
 ! !
 
 
-!DocumentationBuilder class methodsFor: 'initialization'!
+!ClassSelectionAnnouncement class methodsFor: 'instance creation'!
 
 
-initialize
-	self current build
+on: aClass
+	^self new
+		theClass: aClass;
+		yourself
 ! !
 ! !
 
 
 Widget subclass: #DocChapter
 Widget subclass: #DocChapter
-	instanceVariableNames: 'title contents parent'
-	category: 'Documentation'!
+	instanceVariableNames: 'title contents parent level'
+	package: 'Documentation'!
 
 
 !DocChapter methodsFor: 'accessing'!
 !DocChapter methodsFor: 'accessing'!
 
 
-title
-	^title ifNil: ['']
+announcer
+	^DocumentationBuilder current announcer
 !
 !
 
 
-title: aString
-	title := aString
+chapters
+	"A doc chapter can contain sub chapters"
+	^#()
 !
 !
 
 
 contents
 contents
@@ -236,17 +58,18 @@ contents: aString
 	contents := aString
 	contents := aString
 !
 !
 
 
-htmlContents
-	^(Showdown at: #converter) new makeHtml: self contents
+cssClass
+	^'doc_chapter'
 !
 !
 
 
-chapters
-	"A doc chapter can contain sub chapters"
-	^#()
+htmlContents
+	^(Showdown at: #converter) new makeHtml: self contents
 !
 !
 
 
-cssClass
-	^'doc_chapter'
+id
+	"The id is used in url fragments. 
+	It must be unique amoung all chapters"
+	^self title replace: ' ' with: '-'
 !
 !
 
 
 level
 level
@@ -265,28 +88,26 @@ parent: aChapter
 	parent := aChapter
 	parent := aChapter
 !
 !
 
 
-id
-	"The id is used in url fragments. 
-	It must be unique amoung all chapters"
-	^self title replace: ' ' with: '-'
+title
+	^title ifNil: ['']
 !
 !
 
 
-announcer
-	^DocumentationBuilder current announcer
+title: aString
+	title := aString
 ! !
 ! !
 
 
 !DocChapter methodsFor: 'actions'!
 !DocChapter methodsFor: 'actions'!
 
 
-selectClass: aClass
-	DocumentationBuilder current announcer announce: (ClassSelectionAnnouncement on: aClass)
+displayChapter: aChapter
+	DocumentationBuilder current widget displayChapter: aChapter
 !
 !
 
 
 selectChapter: aChapter
 selectChapter: aChapter
 	document location hash: aChapter id
 	document location hash: aChapter id
 !
 !
 
 
-displayChapter: aChapter
-	DocumentationBuilder current widget displayChapter: aChapter
+selectClass: aClass
+	DocumentationBuilder current announcer announce: (ClassSelectionAnnouncement on: aClass)
 ! !
 ! !
 
 
 !DocChapter methodsFor: 'initialization'!
 !DocChapter methodsFor: 'initialization'!
@@ -298,14 +119,6 @@ initialize
 
 
 !DocChapter methodsFor: 'rendering'!
 !DocChapter methodsFor: 'rendering'!
 
 
-renderOn: html
-	html div 
-		class: self cssClass;
-		with: [
-			self renderDocOn: html.
-			self renderLinksOn: html]
-!
-
 renderDocOn: html
 renderDocOn: html
 	| div |
 	| div |
 	html h1 with: self title.
 	html h1 with: self title.
@@ -314,6 +127,17 @@ renderDocOn: html
 	div asJQuery html: self htmlContents
 	div asJQuery html: self htmlContents
 !
 !
 
 
+renderLinksOn: html
+	html ul 
+		class: 'links';
+		with: [
+			self chapters do: [:each |
+				html li with: [
+					html a
+						with: each title;
+						onClick: [self selectChapter: each]]]]
+!
+
 renderNavigationOn: html
 renderNavigationOn: html
 	self parent ifNotNil: [
 	self parent ifNotNil: [
 		html div 
 		html div 
@@ -323,15 +147,12 @@ renderNavigationOn: html
 					onClick: [self selectChapter: self parent]]]
 					onClick: [self selectChapter: self parent]]]
 !
 !
 
 
-renderLinksOn: html
-	html ul 
-		class: 'links';
+renderOn: html
+	html div 
+		class: self cssClass;
 		with: [
 		with: [
-			self chapters do: [:each |
-				html li with: [
-					html a
-						with: each title;
-						onClick: [self selectChapter: each]]]]
+			self renderDocOn: html.
+			self renderLinksOn: html]
 ! !
 ! !
 
 
 !DocChapter methodsFor: 'subscriptions'!
 !DocChapter methodsFor: 'subscriptions'!
@@ -341,57 +162,12 @@ subscribe
 		ann id = self id ifTrue: [self displayChapter: self]]
 		ann id = self id ifTrue: [self displayChapter: self]]
 ! !
 ! !
 
 
-DocChapter subclass: #PackageDocChapter
-	instanceVariableNames: 'package chapters'
-	category: 'Documentation'!
-
-!PackageDocChapter methodsFor: 'accessing'!
-
-package
-	^package
-!
-
-title
-	^'Package ', self package name
-!
-
-chapters
-	^chapters
-!
-
-contents
-	^'Classes in package ', self package name, ':'
-! !
-
-!PackageDocChapter methodsFor: 'initialization'!
-
-initializeWithPackage: aPackage
-	package := aPackage.
-	chapters := (aPackage classes sorted: [:a :b | a name < b name]) collect: [:each |
-		(ClassDocChapter on: each)
-			parent: self;
-			yourself]
-! !
-
-!PackageDocChapter class methodsFor: 'instance creation'!
-
-on: aPackage
-	^self basicNew
-		initializeWithPackage: aPackage;
-		initialize;
-		yourself
-! !
-
 DocChapter subclass: #ClassDocChapter
 DocChapter subclass: #ClassDocChapter
 	instanceVariableNames: 'theClass'
 	instanceVariableNames: 'theClass'
-	category: 'Documentation'!
+	package: 'Documentation'!
 
 
 !ClassDocChapter methodsFor: 'accessing'!
 !ClassDocChapter methodsFor: 'accessing'!
 
 
-theClass
-	^theClass
-!
-
 contents
 contents
 	^self theClass comment isEmpty
 	^self theClass comment isEmpty
 		ifTrue: [self theClass name, ' is not documented yet.']
 		ifTrue: [self theClass name, ' is not documented yet.']
@@ -402,12 +178,16 @@ cssClass
 	^'doc_class ', super cssClass
 	^'doc_class ', super cssClass
 !
 !
 
 
-title
-	^self theClass name
-!
-
 initializeWithClass: aClass
 initializeWithClass: aClass
 	theClass := aClass
 	theClass := aClass
+!
+
+theClass
+	^theClass
+!
+
+title
+	^self theClass name
 ! !
 ! !
 
 
 !ClassDocChapter methodsFor: 'rendering'!
 !ClassDocChapter methodsFor: 'rendering'!
@@ -440,106 +220,22 @@ on: aClass
 		yourself
 		yourself
 ! !
 ! !
 
 
-Widget subclass: #DocumentationWidget
-	instanceVariableNames: 'builder selectedChapter chapterDiv'
-	category: 'Documentation'!
-
-!DocumentationWidget methodsFor: 'accessing'!
-
-builder
-	^builder
-!
-
-builder: aDocumentationBuilder
-	builder := aDocumentationBuilder
-!
-
-chapters
-	^self builder chapters
-!
-
-selectedChapter
-	^selectedChapter ifNil: [selectedChapter := self chapters first]
-!
-
-selectedChapter: aChapter
-	^selectedChapter := aChapter
-! !
-
-!DocumentationWidget methodsFor: 'actions'!
-
-displayChapter: aChapter
-	self selectedChapter: aChapter.
-	self updateChapterDiv
-!
-
-selectChapter: aChapter
-	document location hash: aChapter id
-! !
-
-!DocumentationWidget methodsFor: 'rendering'!
-
-renderOn: html
-	html div 
-		class: 'documentation';
-		with: [
-			self renderMenuOn: html.
-			chapterDiv := html div.
-			self updateChapterDiv]
-!
-
-renderMenuOn: html
-	html div 
-		class: 'menu';
-		with: [
-			html ol with: [
-				self chapters do: [:each |
-					html li with: [
-						self renderChapterMenu: each on: html]]]]
-!
-
-renderChapterMenu: aChapter on: html
-	html a
-		with: aChapter title;
-		onClick: [
-			self selectChapter: aChapter].
-	html ol with: [
-			aChapter chapters do: [:each |
-				html li with: [
-					self renderChapterMenu: each on: html]]]
-! !
-
-!DocumentationWidget methodsFor: 'updating'!
-
-updateChapterDiv
-	chapterDiv contents: [:html |
-		html with: self selectedChapter]
-! !
-
-!DocumentationWidget class methodsFor: 'instance creation'!
-
-on: aBuilder
-	^self new
-		builder: aBuilder;
-		yourself
-! !
-
 DocChapter subclass: #ClassesIndexChapter
 DocChapter subclass: #ClassesIndexChapter
 	instanceVariableNames: ''
 	instanceVariableNames: ''
-	category: 'Documentation'!
+	package: 'Documentation'!
 
 
 !ClassesIndexChapter methodsFor: 'accessing'!
 !ClassesIndexChapter methodsFor: 'accessing'!
 
 
+alphabet
+	^'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+!
+
 cssClass
 cssClass
 	^'index_doc ', super cssClass
 	^'index_doc ', super cssClass
 !
 !
 
 
 title
 title
 	^'Smalltalk classes by index'
 	^'Smalltalk classes by index'
-!
-
-alphabet
-	^'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 ! !
 ! !
 
 
 !ClassesIndexChapter methodsFor: 'rendering'!
 !ClassesIndexChapter methodsFor: 'rendering'!
@@ -557,74 +253,132 @@ renderDocOn: html
 						onClick: [self selectClass: each]]]]]
 						onClick: [self selectClass: each]]]]]
 ! !
 ! !
 
 
-Object subclass: #ClassSelectionAnnouncement
-	instanceVariableNames: 'theClass'
-	category: 'Documentation'!
+DocChapter subclass: #PackageDocChapter
+	instanceVariableNames: 'package chapters'
+	package: 'Documentation'!
 
 
-!ClassSelectionAnnouncement methodsFor: 'accessing'!
+!PackageDocChapter methodsFor: 'accessing'!
 
 
-theClass
-	^theClass
+chapters
+	^chapters
 !
 !
 
 
-theClass: aClass
-	theClass := aClass
-! !
+contents
+	^'Classes in package ', self package name, ':'
+!
 
 
-!ClassSelectionAnnouncement class methodsFor: 'instance creation'!
+package
+	^package
+!
 
 
-on: aClass
-	^self new
-		theClass: aClass;
-		yourself
+title
+	^'Package ', self package name
 ! !
 ! !
 
 
-Object subclass: #ChapterSelectionAnnouncement
-	instanceVariableNames: 'id'
-	category: 'Documentation'!
+!PackageDocChapter methodsFor: 'initialization'!
 
 
-!ChapterSelectionAnnouncement methodsFor: 'accessing'!
+initializeWithPackage: aPackage
+	package := aPackage.
+	chapters := (aPackage classes sorted: [:a :b | a name < b name]) collect: [:each |
+		(ClassDocChapter on: each)
+			parent: self;
+			yourself]
+! !
 
 
-id
-	^id
-!
+!PackageDocChapter class methodsFor: 'instance creation'!
 
 
-id: aString
-	id := aString
+on: aPackage
+	^self basicNew
+		initializeWithPackage: aPackage;
+		initialize;
+		yourself
 ! !
 ! !
 
 
 DocChapter subclass: #TutorialsChapter
 DocChapter subclass: #TutorialsChapter
 	instanceVariableNames: ''
 	instanceVariableNames: ''
-	category: 'Documentation'!
+	package: 'Documentation'!
 
 
 !TutorialsChapter methodsFor: 'accessing'!
 !TutorialsChapter methodsFor: 'accessing'!
 
 
-title
-	^'Tutorials'
+chapters
+	^{ self firstAppChapter. self counterChapter }
 !
 !
 
 
 contents
 contents
 	^'Here''s a serie of tutorials. If you are new to Smalltalk, you can also learn Amber online with [ProfStef](http://www.amber-lang.net/learn.html)'
 	^'Here''s a serie of tutorials. If you are new to Smalltalk, you can also learn Amber online with [ProfStef](http://www.amber-lang.net/learn.html)'
 !
 !
 
 
-chapters
-	^{ self firstAppChapter. self counterChapter }
-!
-
-firstAppChapter
+counterChapter
 	^DocChapter new
 	^DocChapter new
-		title: 'A first application';
+		title: 'The counter application';
 		contents: '
 		contents: '
 
 
-Let''s make Hello World in Amber.
+This tutorial will teach you how to build HTML with Amber using jQuery and the HTMLCanvas API. It is freely adapted from 
+the [Seaside counter example](http://www.seaside.st/about/examples/counter)
 
 
-First, you need a place for your new project. I made a new directory under amber:
+##The counter widget
 
 
-    amber/projects/hello
+The counter is the most basic example of a widget. It allows to increment and decrement a number by clicking a button.
 
 
-This will store your project files. To get started, add a new index.html file to this folder, as well as empty js and st folders.
+Amber already comes with a counter example in the `Examples` package. To avoid class name conflict, we''ll name our counter class `TCounter`.
 
 
-Your index.html can be really basic. The most important thing it does is include amber.js and run loadAmber. Here is a basic index.html you can use:
+    Widget subclass: #TCounter
+        instanceVariableNames: ''count header''
+        package: ''Tutorials''
+
+The first method is used to initialize the component with the default state, in this case we set the counter to 0:
+
+    initialize
+        super initialize.
+        count := 0
+
+The method used for rendering a widget is `#renderOn:`. It takes an instance of HTMLCanvas as parameter. 
+The `header` h1 kept as an instance variable, so when the count value change, we can update it''s contents accordingly.
+
+    renderOn: html
+        header := html h1 
+            with: count asString;
+            yourself.
+        html button
+            with: ''++'';
+            onClick: [self increase].
+        html button
+            with: ''--'';
+            onClick: [self decrease]
+
+The counter is almost ready. All we need now is to implement the two action methods `#increase` and `#decrease` to change the state 
+of our counter and update its header.
+
+    increase
+        count := count + 1.
+        header contents: [:html | html with: count asString]
+
+    decrease
+        count := count - 1.
+        header contents: [:html | html with: count asString]
+
+
+That''s it!! We can now display an instance of TCounter by rendering it on the page using jQuery:
+
+    TCounter new appendToJQuery: ''body'' asJQuery
+
+'
+!
+
+firstAppChapter
+	^DocChapter new
+		title: 'A first application';
+		contents: '
+
+Let''s make Hello World in Amber.
+
+First, you need a place for your new project. I made a new directory under amber:
+
+    amber/projects/hello
+
+This will store your project files. To get started, add a new index.html file to this folder, as well as empty js and st folders.
+
+Your index.html can be really basic. The most important thing it does is include amber.js and run loadAmber. Here is a basic index.html you can use:
 
 
 
 
     <!!DOCTYPE html>
     <!!DOCTYPE html>
@@ -699,60 +453,306 @@ From there, you can create new Smalltalk classes and messages to build up your a
 '
 '
 !
 !
 
 
-counterChapter
+title
+	^'Tutorials'
+! !
+
+Object subclass: #DocumentationBuilder
+	instanceVariableNames: 'chapters announcer widget'
+	package: 'Documentation'!
+
+!DocumentationBuilder methodsFor: 'accessing'!
+
+announcer
+	^announcer ifNil: [announcer := Announcer new]
+!
+
+chapters
+	^chapters ifNil: [chapters := self buildChapters]
+!
+
+widget
+	^widget ifNil: [widget := DocumentationWidget on: self]
+! !
+
+!DocumentationBuilder methodsFor: 'building'!
+
+build
+	self buildOnJQuery: ('body' asJQuery)
+!
+
+buildChapters
+	^((self class methodDictionary values sorted: [:a :b | a selector < b selector])
+		select: [:each | each category = 'chapters'])
+		collect: [:each | self perform: each selector]
+!
+
+buildOn: aCanvas
+	aCanvas with: self widget.
+	self 
+		checkHashChange;
+		checkHash
+!
+
+buildOnJQuery: aJQuery
+	self buildOn: (HTMLCanvas onJQuery: aJQuery)
+! !
+
+!DocumentationBuilder methodsFor: 'chapters'!
+
+ch1introduction
 	^DocChapter new
 	^DocChapter new
-		title: 'The counter application';
+		title: 'Introduction';
 		contents: '
 		contents: '
 
 
-This tutorial will teach you how to build HTML with Amber using jQuery and the HTMLCanvas API. It is freely adapted from 
-the [Seaside counter example](http://www.seaside.st/about/examples/counter)
+##Amber Smalltalk in a nutshell
 
 
-##The counter widget
+Amber is an implementation of the Smalltalk-80 language. It is designed to make client-side web development **faster, easier and more fun** as it allows developers to write HTML5 applications in a live Smalltalk environment!!
 
 
-The counter is the most basic example of a widget. It allows to increment and decrement a number by clicking a button.
+Amber is written in itself, including the IDE and the compiler and it runs **directly inside your browser**. The IDE is fairly complete with a class browser, workspace, transcript, unit test runner, object inspectors, cross reference tools and even a debugger.
 
 
-Amber already comes with a counter example in the `Examples` package. To avoid class name conflict, we''ll name our counter class `TCounter`.
+Noteworthy features:
 
 
-    Widget subclass: #TCounter
-        instanceVariableNames: ''count header''
-        package: ''Tutorials''
+- Amber is semantically and syntactically very close to [Pharo Smalltalk](http://www.pharo-project.org). Pharo is considered the reference implementation.
+- Amber **seamlessly interacts with JavaScript** and can use its full eco system of libraries without any glue code needed.
+- Amber **has no dependencies** and can be used in any JavaScript runtime, not only inside browsers. An important example is [Node.js](http://nodejs.org).
+- Amber is a live Smalltalk that **compiles incrementally into efficient JavaScript** often mapping one-to-one with JavaScript equivalents.
+- Amber has a **Seaside influenced canvas library** to dynamically generate HTML.
 
 
-The first method is used to initialize the component with the default state, in this case we set the counter to 0:
+## Arguments for using Amber
+In our humble opinion the main arguments for using Amber are:
 
 
-    initialize
-        super initialize.
-        count := 0
+- JavaScript is quite a broken language with lots of traps and odd quirks. It is the assembler of the Internet which is cool, but we don''t want to write in it.
+- Smalltalk as a language is immensely cleaner and more mature, both syntactically and semantically.
+- Smalltalk has a simple class model with a lightweight syntax for closures, it is in many ways a perfect match for the Good Parts of JavaScript.
+- Having a true live interactive incremental development environment where you can build your application directly in the browser is unbeatable.
 
 
-The method used for rendering a widget is `#renderOn:`. It takes an instance of HTMLCanvas as parameter. 
-The `header` h1 kept as an instance variable, so when the count value change, we can update it''s contents accordingly.
+## Disclaimer
 
 
-    renderOn: html
-        header := html h1 
-            with: count asString;
-            yourself.
-        html button
-            with: ''++'';
-            onClick: [self increase].
-        html button
-            with: ''--'';
-            onClick: [self decrease]
+This documentation doesn''t aim to teach Smalltalk. 
+Knowledge of Smalltalk is needed to understand the topics covered in this documentation. 
+If you want to learn the Smalltalk language, you can read the excellent [Pharo By Example](http://www.pharobyexample.org) book.
+'
+!
 
 
-The counter is almost ready. All we need now is to implement the two action methods `#increase` and `#decrease` to change the state 
-of our counter and update its header.
+ch2differencesWithOtherSmalltalks
+	^DocChapter new
+		title: 'Differences with other Smalltalks';
+		contents: '
+Amber has some differences with other Smalltalk implementations. This makes porting code a non-trivial thing, but still quite manageable.
+Because it maps Smalltalk constructs one-to-one with the JavaScript equivalent, including Smalltalk classes to JavaScript constructors, the core class library is simplified compared to Pharo Smalltalk.
+And since we want Amber to be useful in building lean browser apps we can''t let it bloat too much.
 
 
-    increase
-        count := count + 1.
-        header contents: [:html | html with: count asString]
+But apart from missing things other Smalltalks may have, there are also things that are plain different:
 
 
-    decrease
-        count := count - 1.
-        header contents: [:html | html with: count asString]
+- The collection class hierarchy is much simpler compared to most Smalltalk implementations. In part this is because we want to map reasonably well with JavaScript counter parts.
+- As of today, there is no SortedCollection. The size of arrays is dynamic, and they behave like an ordered collection. They can also be sorted with the `#sort*` methods.
+- The `Date` class behaves like the `Date` and `TimeStamp` classes in Pharo Smalltalk. Therefore both `Date today` and `Date now` are valid in Amber.
+- Amber does not have class Character, but `String` does implement some of Character behavior so a single character String can work as a Character.
+- Amber does support **class instance variables**, but not class variables.
+- Amber only has global classes and packages, but not arbitrary objects. Use classes instead like `Smalltalk current` instead of `Smalltalk` etc.
+- Amber does not support pool dictionaries.
+- Amber uses **< ...javascript code... >** to inline JavaScript code and does not have pragmas.
+- Amber does not have class categories. The left side in the browser lists real Packages, but they feel much the same.
+'
+!
 
 
+ch3GettingStarted
+	^DocChapter new
+		title: 'Getting started';
+		contents: '
+To get started hacking in Amber you can basically take three routes, independent of your platform:
 
 
-That''s it!! We can now display an instance of TCounter by rendering it on the page using jQuery:
+1. Just **try it out directly** at [www.amber-lang.net](http://www.amber-lang.net) - click the **Class browser** button there. But you will **not be able to save any code you write**!! 
+    Still, it works fine for looking at the IDE and playing around. Just **don''t press F5/reload** - it will lose any code you have written.
+2. Download an Amber zip-ball, install [Nodejs](http://www.nodejs.org), fire up the Amber server and then open Amber from localhost - then you **can save code**. Detailed instructions are below!!
+3. Same as above but install git first and get a proper clone from [http://github.com/NicolasPetton/amber](http://github.com/NicolasPetton/amber) instead of a zip/tar-ball. 
+    If you want to **contribute to Amber itself** this is really what you want to do. In fact, in most cases this is what you want to do. It requires installing git first, but it is quite simple - although we leave this bit as an "exercise to the reader" :)
 
 
-    TCounter new appendToJQuery: ''body'' asJQuery
+**PLEASE NOTE:** Amber core developers use Linux. 
+We do not want to introduce dependencies that aren''t cross platform - but currently amberc (the command line compiler) is a bash script and we also use Makefiles 
+(for building Amber itself and server side examples) written on Linux/Unix. So using Windows is currently a bit limited - you can''t run "make" in the .st directory to rebuild whole of Amber for example.
+ BUT... if you only want to use Amber to build web client apps and not really get involved in hacking Amber itself - then you should be fine!!
+
+## Downloading Amber
+Currently you can download in zip or tar-ball format, either cutting edge or a release. [Downloads are available here](https://github.com/NicolasPetton/amber/archives/amber). 
+
+Unpack wherever you like, but I would rename the directory that is unpacked to something slightly shorter - like say "amber". :)
+And yes, at this point you can double click the index.html file in the amber directory to get the IDE up, but again, **you will not be able to save code**. So please continue below :)
+
+## Installing Node.js
+[Node](http://www.nodejs.org) (for short) is simply the V8 Javascript VM from Google (used in Chrome) hooked together with some hard core C-libraries for doing "evented I/O".
+Basically it''s JavaScript for the server - on asynch steroids. Amber runs fine in Node and we use it for several Amber tools, like amberc (the command line Amber compiler) or the Amber server (see below). 
+There are also several Amber-Node examples to look at if you want to play with running Amber programs server side. **In short - you really want to install Nodejs. :)**
 
 
+- Installing Node on Linux can be done using your package tool of choice (`apt-get install nodejs` for example) or any other way described at [the download page](http://nodejs.org/#download).
+- Installing Node on MacOS or Windows is probably done best by using the [installers available at Nodejs.org](http://nodejs.org/#download).
+
+## Starting Amber server
+Nicolas has written a minimal webDAV server that is the easiest way to get up and running Amber with the ability to save code. This little server is written in... Amber!! 
+And it runs on top of Node. So to start it up serving your brand new directory tree of sweet Amber you do:
+
+	cd amber	(or whatever you called the directory you unpackaged)
+	./bin/server	(in windows you type `node server\server.js` instead)
+
+It should say it is listening on port 4000. If it does, hooray!! That means both Node and Amber are good. In Windows you might get a question about opening that port in the local firewall - yep, do it!!
+
+## Firing up Amber
+The Amber IDE is written in... Amber. It uses [jQuery](http://jquery.com) and runs right in your browser as a ... well, a web page. 
+We could open it up just using a file url - but the reason we performed the previous steps is so that we can load the IDE web page from a server that can handle PUTs (webDAV) of source code. 
+According to web security Amber can only do PUT back to the same server it was loaded from. Thus we instead want to open it [through our little server now listening on port 4000](http://localhost:4000/index.html).
+Clicking that link and then pressing the **Class browser** should get your Amber IDE running with the ability to commit modified packages locally.
+
+To verify that you can indeed commit now - just select a Package in the browser, like say "Examples" and press the **Commit** button below. **If all goes well nothing happens :)**. 
+So in order to really know if it worked we can check the modified date on the files **amber/st/Examples.st**, **amber/js/Examples.js** and **amber/js/Examples.deploy.js** - they should be brand new.
+
+NOTE: We can use any webDAV server and Apache2 has been used earlier and works fine. But the Amber server is smaller and simpler to start.
 '
 '
+!
+
+ch4Tutorials
+	^TutorialsChapter new
+!
+
+ch5Index
+	^ClassesIndexChapter new
+!
+
+ch6KernelObjects
+	^PackageDocChapter on: (Package named: 'Kernel-Objects')
+!
+
+ch7KernelClasses
+	^PackageDocChapter on: (Package named: 'Kernel-Classes')
+!
+
+ch8KernelCollection
+	^PackageDocChapter on: (Package named: 'Kernel-Collections')
+!
+
+ch9KernelMethods
+	^PackageDocChapter on: (Package named: 'Kernel-Methods')
+! !
+
+!DocumentationBuilder methodsFor: 'routing'!
+
+checkHash
+	| hash presentation |
+	hash := document location hash  replace: '^#' with: ''.
+	self announcer announce: (ChapterSelectionAnnouncement new 
+		id: hash; 
+		yourself)
+!
+
+checkHashChange
+	(window jQuery: window) bind: 'hashchange' do: [self checkHash]
+! !
+
+!DocumentationBuilder methodsFor: 'updating'!
+
+update
+	chapters := nil.
+	announcer := nil.
+	widget := nil.
+	(window jQuery: '.documentation') remove.
+	self build
+! !
+
+DocumentationBuilder class instanceVariableNames: 'current'!
+
+!DocumentationBuilder class methodsFor: 'accessing'!
+
+current
+	^current ifNil: [current := self new]
+! !
+
+!DocumentationBuilder class methodsFor: 'initialization'!
+
+initialize
+	self current build
+! !
+
+Widget subclass: #DocumentationWidget
+	instanceVariableNames: 'builder selectedChapter chapterDiv'
+	package: 'Documentation'!
+
+!DocumentationWidget methodsFor: 'accessing'!
+
+builder
+	^builder
+!
+
+builder: aDocumentationBuilder
+	builder := aDocumentationBuilder
+!
+
+chapters
+	^self builder chapters
+!
+
+selectedChapter
+	^selectedChapter ifNil: [selectedChapter := self chapters first]
+!
+
+selectedChapter: aChapter
+	^selectedChapter := aChapter
+! !
+
+!DocumentationWidget methodsFor: 'actions'!
+
+displayChapter: aChapter
+	self selectedChapter: aChapter.
+	self updateChapterDiv
+!
+
+selectChapter: aChapter
+	document location hash: aChapter id
+! !
+
+!DocumentationWidget methodsFor: 'rendering'!
+
+renderChapterMenu: aChapter on: html
+	html a
+		with: aChapter title;
+		onClick: [
+			self selectChapter: aChapter].
+	html ol with: [
+			aChapter chapters do: [:each |
+				html li with: [
+					self renderChapterMenu: each on: html]]]
+!
+
+renderMenuOn: html
+	html div 
+		class: 'menu';
+		with: [
+			html ol with: [
+				self chapters do: [:each |
+					html li with: [
+						self renderChapterMenu: each on: html]]]]
+!
+
+renderOn: html
+	html div 
+		class: 'documentation';
+		with: [
+			self renderMenuOn: html.
+			chapterDiv := html div.
+			self updateChapterDiv]
+! !
+
+!DocumentationWidget methodsFor: 'updating'!
+
+updateChapterDiv
+	chapterDiv contents: [:html |
+		html with: self selectedChapter]
+! !
+
+!DocumentationWidget class methodsFor: 'instance creation'!
+
+on: aBuilder
+	^self new
+		builder: aBuilder;
+		yourself
 ! !
 ! !
 
 

+ 1 - 1
st/IDE.st

@@ -1205,7 +1205,7 @@ updateSourceAndButtons
                 currentProtocol := selectedProtocol.
                 currentProtocol := selectedProtocol.
                 (currentProtocol isNil and: [ selectedMethod notNil ])
                 (currentProtocol isNil and: [ selectedMethod notNil ])
                 	ifTrue: [ currentProtocol := selectedMethod category].
                 	ifTrue: [ currentProtocol := selectedMethod category].
-				self protocols do: [:each |
+				self protocols do: [:each | | option |
 					option := html option with: each.
 					option := html option with: each.
 					currentProtocol = each ifTrue: [ option at: 'selected' put: 'selected' ] ]].
 					currentProtocol = each ifTrue: [ option at: 'selected' put: 'selected' ] ]].
 		selectedMethod isNil ifFalse: [
 		selectedMethod isNil ifFalse: [

+ 14 - 7
st/Kernel-Classes.st

@@ -449,13 +449,17 @@ superclass: aClass subclass: aString instanceVariableNames: aString2 package: aS
 !ClassBuilder methodsFor: 'private'!
 !ClassBuilder methodsFor: 'private'!
 
 
 addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
 addSubclassOf: aClass named: aString instanceVariableNames: aCollection package: packageName
-	
-    (Smalltalk current at: aString) ifNotNil: [ 
-    	^ self 
-        	migrateClassNamed: aString 
-            superclass: aClass 
-            instanceVariableNames: aCollection 
-            package: packageName ].
+    | theClass |
+    
+    theClass := Smalltalk current at: aString.
+    
+   	theClass ifNotNil: [ 
+    	theClass superclass == aClass ifFalse: [
+    		^ self 
+        		migrateClassNamed: aString 
+           	 	superclass: aClass 
+           	 	instanceVariableNames: aCollection 
+            	package: packageName ] ].
 
 
 	^ self 
 	^ self 
     	basicAddSubclassOf: aClass 
     	basicAddSubclassOf: aClass 
@@ -527,6 +531,7 @@ instanceVariableNamesFor: aString
 !
 !
 
 
 migrateClass: aClass superclass: anotherClass
 migrateClass: aClass superclass: anotherClass
+	console log: aClass name.
 	self 
 	self 
     	migrateClassNamed: aClass name
     	migrateClassNamed: aClass name
         superclass: anotherClass
         superclass: anotherClass
@@ -537,6 +542,8 @@ migrateClass: aClass superclass: anotherClass
 migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
 migrateClassNamed: aString superclass: aClass instanceVariableNames: aCollection package: packageName
 	| oldClass newClass |
 	| oldClass newClass |
     
     
+    console log: '*** MIGRATING ', aString.
+    
     oldClass := Smalltalk current at: aString.
     oldClass := Smalltalk current at: aString.
     
     
     "Rename the old class for existing instances"
     "Rename the old class for existing instances"

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است