Ver código fonte

Merge branch 'master' into debugger

Conflicts:
	js/Compiler-IR.deploy.js
	js/Compiler-IR.js
	js/Compiler-Interpreter.deploy.js
	js/Compiler-Interpreter.js
	js/Compiler-Semantic.deploy.js
	js/Compiler-Semantic.js
	js/Helios-Browser.deploy.js
	js/Helios-Browser.js
	js/Helios-Core.deploy.js
	js/Helios-Core.js
	js/Helios-References.deploy.js
	js/Helios-References.js
	js/Helios-Workspace.deploy.js
	js/Helios-Workspace.js
	js/Kernel-Classes.deploy.js
	js/Kernel-Classes.js
	js/Kernel-Collections.deploy.js
	js/Kernel-Collections.js
	js/SUnit.deploy.js
	js/SUnit.js
	js/boot.js
	st/Kernel-Collections.st
Nicolas Petton 10 anos atrás
pai
commit
a63b725583
74 arquivos alterados com 2498 adições e 406 exclusões
  1. 3 0
      API-CHANGES.txt
  2. 7 0
      bin/amberc
  3. 6 0
      bin/amberc.js
  4. 361 13
      cli/js/AmberCli.deploy.js
  5. 518 18
      cli/js/AmberCli.js
  6. 585 26
      cli/js/amber-cli.js
  7. 155 8
      cli/st/AmberCli.st
  8. 6 2
      grunt/tasks/grunt-amberc.js
  9. 4 4
      js/Canvas.deploy.js
  10. 4 4
      js/Canvas.js
  11. 1 1
      js/Compiler-AST.deploy.js
  12. 1 1
      js/Compiler-AST.js
  13. 2 1
      js/Compiler-Core.deploy.js
  14. 3 2
      js/Compiler-Core.js
  15. 1 1
      js/Compiler-Exceptions.deploy.js
  16. 1 1
      js/Compiler-Exceptions.js
  17. 36 11
      js/Compiler-IR.deploy.js
  18. 47 12
      js/Compiler-IR.js
  19. 8 7
      js/Compiler-Inlining.deploy.js
  20. 9 8
      js/Compiler-Inlining.js
  21. 15 15
      js/Compiler-Interpreter.deploy.js
  22. 17 17
      js/Compiler-Interpreter.js
  23. 12 11
      js/Compiler-Semantic.deploy.js
  24. 14 13
      js/Compiler-Semantic.js
  25. 1 1
      js/Examples.deploy.js
  26. 1 1
      js/Examples.js
  27. 10 10
      js/Helios-Browser.deploy.js
  28. 10 10
      js/Helios-Browser.js
  29. 13 13
      js/Helios-Core.deploy.js
  30. 13 13
      js/Helios-Core.js
  31. 4 4
      js/Helios-Debugger.deploy.js
  32. 4 4
      js/Helios-Debugger.js
  33. 8 11
      js/Helios-Inspector.deploy.js
  34. 9 12
      js/Helios-Inspector.js
  35. 4 4
      js/Helios-KeyBindings.deploy.js
  36. 4 4
      js/Helios-KeyBindings.js
  37. 4 4
      js/Helios-Layout.deploy.js
  38. 4 4
      js/Helios-Layout.js
  39. 1 1
      js/Helios-References.deploy.js
  40. 1 1
      js/Helios-References.js
  41. 2 2
      js/Helios-Transcript.deploy.js
  42. 2 2
      js/Helios-Transcript.js
  43. 6 6
      js/Helios-Workspace.deploy.js
  44. 6 6
      js/Helios-Workspace.js
  45. 10 10
      js/IDE.deploy.js
  46. 10 10
      js/IDE.js
  47. 2 2
      js/Kernel-Announcements.deploy.js
  48. 2 2
      js/Kernel-Announcements.js
  49. 18 3
      js/Kernel-Classes.deploy.js
  50. 24 4
      js/Kernel-Classes.js
  51. 48 8
      js/Kernel-Collections.deploy.js
  52. 65 10
      js/Kernel-Collections.js
  53. 5 5
      js/Kernel-Methods.deploy.js
  54. 5 5
      js/Kernel-Methods.js
  55. 42 7
      js/Kernel-Objects.deploy.js
  56. 58 8
      js/Kernel-Objects.js
  57. 60 1
      js/Kernel-Tests.deploy.js
  58. 81 1
      js/Kernel-Tests.js
  59. 5 5
      js/SUnit.deploy.js
  60. 5 5
      js/SUnit.js
  61. 1 1
      js/Spaces.deploy.js
  62. 1 1
      js/Spaces.js
  63. 28 8
      js/boot.js
  64. 2 2
      package.json
  65. 1 0
      st/Compiler-Core.st
  66. 11 2
      st/Compiler-IR.st
  67. 1 0
      st/Compiler-Inlining.st
  68. 7 7
      st/Compiler-Interpreter.st
  69. 3 2
      st/Compiler-Semantic.st
  70. 1 3
      st/Helios-Inspector.st
  71. 7 0
      st/Kernel-Classes.st
  72. 18 4
      st/Kernel-Collections.st
  73. 16 1
      st/Kernel-Objects.st
  74. 38 0
      st/Kernel-Tests.st

+ 3 - 0
API-CHANGES.txt

@@ -52,6 +52,9 @@
 + Environment>>removeProtocol:
 + Environment>>renameProtocol:to:in:
 + CompiledMethod>>protocol:
++ Smalltalk>>globalJsVariables
++ Smalltalk>>addGlobalJsVariable:
++ Smalltalk>>deleteGlobalJsVariable:
 
 
 - Object>>storeOn:

+ 7 - 0
bin/amberc

@@ -41,6 +41,9 @@ function handle_options(optionsArray, amber_dir) {
 			case '-l':
 				defaults.load.push.apply(defaults.load, optionsArray.shift().split(','));
 				break;
+			case '-g':
+				defaults.jsGlobals.push.apply(defaults.jsGlobals, optionsArray.shift().split(','));
+				break;
 			case '-i':
 				defaults.init = optionsArray.shift();
 				break;
@@ -139,6 +142,10 @@ function print_usage() {
 	console.log('     Add listed JavaScript libraries in listed order.');
 	console.log('     Libraries are not separated by spaces or end with .js.');
 	console.log('');
+	console.log('  -g jsGlobal1,jsGlobal2');
+	console.log('     Comma separated list of JS global variable names.');
+	console.log('     The names are added to a list containing "window", "document" and others.');
+	console.log('');
 	console.log('  -i init_file');
 	console.log('     Add library initializer <init_file> instead of default $AMBER/js/init.js ');
 	console.log('');

+ 6 - 0
bin/amberc.js

@@ -106,6 +106,7 @@ var createDefaults = function(amber_dir, finished_callback){
 		'mainfile': undefined,
 		'stFiles': [],
 		'jsFiles': [],
+		'jsGlobals': [],
 		'closure': false,
 		'closure_parts': false,
 		'closure_full': false,
@@ -422,6 +423,11 @@ AmberC.prototype.create_compiler = function(compilerFilesArray) {
 		console.log('Compiler loaded');
 		self.defaults.smalltalk.ErrorHandler._setCurrent_(self.defaults.smalltalk.RethrowErrorHandler._new());
 
+		if(0 != self.defaults.jsGlobals.length) {
+			var jsGlobalVariables = self.defaults.smalltalk.globalJsVariables;
+			jsGlobalVariables.push.apply(jsGlobalVariables, self.defaults.jsGlobals);
+		}
+
 		self.compile();
 	});
 

+ 361 - 13
cli/js/AmberCli.deploy.js

@@ -884,7 +884,62 @@ messageSends: [",", "replace:with:", "asUppercase", "second"]}),
 smalltalk.FileServer.klass);
 
 
-smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'AmberCli');
+smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util', 'session', 'resultCount'], 'AmberCli');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addVariableNamed:to:",
+fn: function (aString,anObject){
+var self=this;
+var newClass,newObject;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+newClass=self._subclass_withVariable_(_st(anObject)._class(),aString);
+self._encapsulateVariable_withValue_in_(aString,anObject,newClass);
+newObject=_st(newClass)._new();
+self._setPreviousVariablesFor_from_(newObject,anObject);
+$1=newObject;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"addVariableNamed:to:",{aString:aString,anObject:anObject,newClass:newClass,newObject:newObject},smalltalk.Repl)})},
+messageSends: ["subclass:withVariable:", "class", "encapsulateVariable:withValue:in:", "new", "setPreviousVariablesFor:from:"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "assignNewVariable:do:",
+fn: function (buffer,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$5,$7,$6,$4,$1;
+$1=self._parseAssignment_do_(buffer,(function(name,expr){
+var varName,value;
+return smalltalk.withContext(function($ctx2) {
+$2=name;
+if(($receiver = $2) == nil || $receiver == undefined){
+varName=self._nextResultName();
+} else {
+varName=$2;
+};
+varName;
+self["@session"]=self._addVariableNamed_to_(varName,self["@session"]);
+self["@session"];
+$3=self;
+$5=_st(varName).__comma(" := ");
+$7=expr;
+if(($receiver = $7) == nil || $receiver == undefined){
+$6=buffer;
+} else {
+$6=$7;
+};
+$4=_st($5).__comma($6);
+value=_st($3)._eval_on_($4,self["@session"]);
+value;
+return _st(aBlock)._value_value_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({name:name,expr:expr,varName:varName,value:value},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"assignNewVariable:do:",{buffer:buffer,aBlock:aBlock},smalltalk.Repl)})},
+messageSends: ["parseAssignment:do:", "ifNil:", "nextResultName", "addVariableNamed:to:", "eval:on:", ",", "value:value:"]}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "close",
@@ -902,19 +957,38 @@ selector: "createInterface",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 self["@interface"]=_st(self["@readline"])._createInterface_stdout_(_st(process)._stdin(),_st(process)._stdout());
 _st(self["@interface"])._on_do_("line",(function(buffer){
 return smalltalk.withContext(function($ctx2) {
-return self._eval_(buffer);
+return self._processLine_(buffer);
 }, function($ctx2) {$ctx2.fillBlock({buffer:buffer},$ctx1)})}));
 _st(self["@interface"])._on_do_("close",(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._close();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-self._setPrompt();
+$1=self;
+_st($1)._printWelcome();
+_st($1)._setupHotkeys();
+$2=_st($1)._setPrompt();
 _st(self["@interface"])._prompt();
 return self}, function($ctx1) {$ctx1.fill(self,"createInterface",{},smalltalk.Repl)})},
-messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"]}),
+messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "processLine:", "close", "printWelcome", "setupHotkeys", "setPrompt", "prompt"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "encapsulateVariable:withValue:in:",
+fn: function (aString,anObject,aClass){
+var self=this;
+var compiler;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+compiler=_st($Compiler())._new();
+_st(compiler)._install_forClass_category_(_st(_st(_st(aString).__comma(": anObject ^ ")).__comma(aString)).__comma(" := anObject"),aClass,"session");
+_st(compiler)._install_forClass_category_(_st(_st(aString).__comma(" ^ ")).__comma(aString),aClass,"session");
+return self}, function($ctx1) {$ctx1.fill(self,"encapsulateVariable:withValue:in:",{aString:aString,anObject:anObject,aClass:aClass,compiler:compiler},smalltalk.Repl)})},
+messageSends: ["new", "install:forClass:category:", ","]}),
 smalltalk.Repl);
 
 smalltalk.addMethod(
@@ -922,19 +996,31 @@ smalltalk.method({
 selector: "eval:",
 fn: function (buffer){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._eval_on_(buffer,_st($DoIt())._new());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer},smalltalk.Repl)})},
+messageSends: ["eval:on:", "new"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "eval:on:",
+fn: function (buffer,anObject){
+var self=this;
 var result;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
 function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3;
 $1=_st(buffer)._isEmpty();
 if(! smalltalk.assert($1)){
 self._try_catch_((function(){
 return smalltalk.withContext(function($ctx2) {
-result=_st(_st($Compiler())._new())._evaluateExpression_(buffer);
-result;
-return _st($Transcript())._show_(result);
+result=_st(_st($Compiler())._new())._evaluateExpression_on_(buffer,anObject);
+return result;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(function(e){
 return smalltalk.withContext(function($ctx2) {
 $2=_st(e)._isSmalltalkError();
@@ -945,9 +1031,28 @@ return _st(_st(process)._stdout())._write_(_st(e)._jsStack());
 };
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 };
-_st(self["@interface"])._prompt();
-return self}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer,result:result},smalltalk.Repl)})},
-messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:", "new", "show:", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty", "prompt"]}),
+$3=result;
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:on:",{buffer:buffer,anObject:anObject,result:result},smalltalk.Repl)})},
+messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:on:", "new", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "executeCommand:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(aString).__eq(":q");
+if(smalltalk.assert($2)){
+$1=_st(process)._exit();
+} else {
+$1=false;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"executeCommand:",{aString:aString},smalltalk.Repl)})},
+messageSends: ["ifTrue:ifFalse:", "exit", "="]}),
 smalltalk.Repl);
 
 smalltalk.addMethod(
@@ -955,12 +1060,186 @@ smalltalk.method({
 selector: "initialize",
 fn: function (){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
 return smalltalk.withContext(function($ctx1) { 
 smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@session"]=_st($DoIt())._new();
 self["@readline"]=_st(require)._value_("readline");
 self["@util"]=_st(require)._value_("util");
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Repl)})},
-messageSends: ["initialize", "value:"]}),
+messageSends: ["initialize", "new", "value:"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "instanceVariableNamesFor:",
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(aClass)._superclass();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(aClass)._instanceVariableNames();
+} else {
+$1=_st(_st(aClass)._instanceVariableNames())._copyWithAll_(self._instanceVariableNamesFor_(_st(aClass)._superclass()));
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"instanceVariableNamesFor:",{aClass:aClass},smalltalk.Repl)})},
+messageSends: ["ifNotNil:ifNil:", "copyWithAll:", "instanceVariableNamesFor:", "superclass", "instanceVariableNames"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isIdentifier:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(aString)._match_("^[a-z_]\x5cw+$"._asRegexp());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isIdentifier:",{aString:aString},smalltalk.Repl)})},
+messageSends: ["match:", "asRegexp"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isVariableDefined:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._instanceVariableNamesFor_(_st(self["@session"])._class()))._includes_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isVariableDefined:",{aString:aString},smalltalk.Repl)})},
+messageSends: ["includes:", "instanceVariableNamesFor:", "class"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "nextResultName",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self["@resultCount"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@resultCount"]=(1);
+} else {
+self["@resultCount"]=_st(self["@resultCount"]).__plus((1));
+};
+$2="res".__comma(_st(self["@resultCount"])._asString());
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"nextResultName",{},smalltalk.Repl)})},
+messageSends: ["ifNotNil:ifNil:", "+", ",", "asString"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onKeyPress:",
+fn: function (key){
+var self=this;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(key)._ctrl())._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(key)._name()).__eq("l");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
+var esc,cls;
+esc=_st($String())._fromCharCode_((27));
+esc;
+cls=_st(_st(_st(esc).__comma("[2J")).__comma(esc)).__comma("[0;0f");
+cls;
+_st(_st(process)._stdout())._write_(cls);
+_st(self["@interface"])._prompt();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"onKeyPress:",{key:key},smalltalk.Repl)})},
+messageSends: ["ifTrue:", "fromCharCode:", ",", "write:", "stdout", "prompt", "and:", "=", "name", "ctrl"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "parseAssignment:do:",
+fn: function (aString,aBlock){
+var self=this;
+var assignment;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+assignment=_st(_st(aString)._tokenize_(":="))._collect_((function(s){
+return smalltalk.withContext(function($ctx2) {
+return _st(s)._trimBoth();
+}, function($ctx2) {$ctx2.fillBlock({s:s},$ctx1)})}));
+$2=_st(_st(_st(assignment)._size()).__eq((2)))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._isIdentifier_(_st(assignment)._first());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value_value_(_st(assignment)._first(),_st(assignment)._last());
+} else {
+$1=_st(aBlock)._value_value_(nil,nil);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"parseAssignment:do:",{aString:aString,aBlock:aBlock,assignment:assignment},smalltalk.Repl)})},
+messageSends: ["collect:", "trimBoth", "tokenize:", "ifTrue:ifFalse:", "value:value:", "first", "last", "and:", "isIdentifier:", "=", "size"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "presentResultNamed:withValue:",
+fn: function (varName,value){
+var self=this;
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=$Transcript();
+_st($1)._show_(_st(_st(_st(_st(varName).__comma(": ")).__comma(_st(_st(value)._class())._name())).__comma(" = ")).__comma(_st(value)._asString()));
+$2=_st($1)._cr();
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"presentResultNamed:withValue:",{varName:varName,value:value},smalltalk.Repl)})},
+messageSends: ["show:", ",", "asString", "name", "class", "cr", "prompt"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "printWelcome",
+fn: function (){
+var self=this;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st($Transcript())._show_(_st(_st(_st("Welcome to Amber version ".__comma(_st(_st($Smalltalk())._current())._version())).__comma(" (NodeJS ")).__comma(_st(_st(process)._versions())._node())).__comma(")."));
+$1=$Transcript();
+_st($1)._show_("Type :q to exit.");
+$2=_st($1)._cr();
+return self}, function($ctx1) {$ctx1.fill(self,"printWelcome",{},smalltalk.Repl)})},
+messageSends: ["show:", ",", "node", "versions", "version", "current", "cr"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "processLine:",
+fn: function (buffer){
+var self=this;
+var show;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+show=(function(varName,value){
+return smalltalk.withContext(function($ctx2) {
+return self._presentResultNamed_withValue_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({varName:varName,value:value},$ctx1)})});
+$1=self._executeCommand_(buffer);
+if(! smalltalk.assert($1)){
+$2=self._isVariableDefined_(buffer);
+if(smalltalk.assert($2)){
+_st(show)._value_value_(buffer,_st(self["@session"])._perform_(buffer));
+} else {
+self._assignNewVariable_do_(buffer,show);
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"processLine:",{buffer:buffer,show:show},smalltalk.Repl)})},
+messageSends: ["presentResultNamed:withValue:", "ifFalse:", "ifTrue:ifFalse:", "value:value:", "perform:", "assignNewVariable:do:", "isVariableDefined:", "executeCommand:"]}),
 smalltalk.Repl);
 
 smalltalk.addMethod(
@@ -974,6 +1253,20 @@ return "amber >> ";
 messageSends: []}),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setPreviousVariablesFor:from:",
+fn: function (newObject,oldObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._instanceVariableNamesFor_(_st(oldObject)._class()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newObject)._perform_withArguments_(_st(each).__comma(":"),[_st(oldObject)._perform_(each)]);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setPreviousVariablesFor:from:",{newObject:newObject,oldObject:oldObject},smalltalk.Repl)})},
+messageSends: ["do:", "perform:withArguments:", ",", "perform:", "instanceVariableNamesFor:", "class"]}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setPrompt",
@@ -985,6 +1278,61 @@ return self}, function($ctx1) {$ctx1.fill(self,"setPrompt",{},smalltalk.Repl)})}
 messageSends: ["setPrompt:", "prompt"]}),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupHotkeys",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(_st(process)._stdin())._on_do_("keypress",(function(s,key){
+return smalltalk.withContext(function($ctx2) {
+$1=key;
+if(($receiver = $1) == nil || $receiver == undefined){
+return $1;
+} else {
+return self._onKeyPress_(key);
+};
+}, function($ctx2) {$ctx2.fillBlock({s:s,key:key},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setupHotkeys",{},smalltalk.Repl)})},
+messageSends: ["on:do:", "ifNotNil:", "onKeyPress:", "stdin"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclass:withVariable:",
+fn: function (aClass,varName){
+var self=this;
+function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st($ClassBuilder())._new())._addSubclassOf_named_instanceVariableNames_package_(aClass,_st(self._subclassNameFor_(aClass))._asSymbol(),[varName],"Compiler-Core");
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclass:withVariable:",{aClass:aClass,varName:varName},smalltalk.Repl)})},
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "asSymbol", "subclassNameFor:", "new"]}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclassNameFor:",
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(_st(aClass)._name())._matchesOf_("\x5cd+$");
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(_st(aClass)._name()).__comma("2");
+} else {
+var counter;
+counter=_st(_st(_st(_st(_st(aClass)._name())._matchesOf_("\x5cd+$"))._first())._asNumber()).__plus((1));
+counter;
+$1=_st(_st(aClass)._name())._replaceRegexp_with_("\x5cd+$"._asRegexp(),_st(counter)._asString());
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclassNameFor:",{aClass:aClass},smalltalk.Repl)})},
+messageSends: ["ifNotNil:ifNil:", "+", "asNumber", "first", "matchesOf:", "name", "replaceRegexp:with:", "asRegexp", "asString", ","]}),
+smalltalk.Repl);
+
 
 smalltalk.addMethod(
 smalltalk.method({

+ 518 - 18
cli/js/AmberCli.js

@@ -1116,8 +1116,94 @@ referencedClasses: []
 smalltalk.FileServer.klass);
 
 
-smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'AmberCli');
+smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util', 'session', 'resultCount', 'commands'], 'AmberCli');
 smalltalk.Repl.comment="I am a class representing a REPL (Read Evaluate Print Loop) and provide a command line interface to Amber Smalltalk.\x0aOn the prompt you can type Amber statements which will be evaluated after pressing <Enter>.\x0aThe evaluation is comparable with executing a 'DoIt' in a workspace.\x0a\x0aMy runtime requirement is a functional Node.js executable with working Readline support.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addVariableNamed:to:",
+category: 'private',
+fn: function (aString,anObject){
+var self=this;
+var newClass,newObject;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+newClass=self._subclass_withVariable_(_st(anObject)._class(),aString);
+self._encapsulateVariable_withValue_in_(aString,anObject,newClass);
+newObject=_st(newClass)._new();
+self._setPreviousVariablesFor_from_(newObject,anObject);
+$1=newObject;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"addVariableNamed:to:",{aString:aString,anObject:anObject,newClass:newClass,newObject:newObject},smalltalk.Repl)})},
+args: ["aString", "anObject"],
+source: "addVariableNamed: aString to: anObject\x0a\x09| newClass newObject |\x0a\x09newClass := self subclass: anObject class withVariable: aString.\x0a\x09self encapsulateVariable: aString withValue: anObject in: newClass.\x0a\x09newObject := newClass new.\x0a\x09self setPreviousVariablesFor: newObject from: anObject.\x0a\x09^ newObject",
+messageSends: ["subclass:withVariable:", "class", "encapsulateVariable:withValue:in:", "new", "setPreviousVariablesFor:from:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "assignNewVariable:do:",
+category: 'private',
+fn: function (buffer,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$5,$7,$6,$4,$1;
+$1=self._parseAssignment_do_(buffer,(function(name,expr){
+var varName,value;
+return smalltalk.withContext(function($ctx2) {
+$2=name;
+if(($receiver = $2) == nil || $receiver == undefined){
+varName=self._nextResultName();
+} else {
+varName=$2;
+};
+varName;
+self["@session"]=self._addVariableNamed_to_(varName,self["@session"]);
+self["@session"];
+$3=self;
+$5=_st(varName).__comma(" := ");
+$7=expr;
+if(($receiver = $7) == nil || $receiver == undefined){
+$6=buffer;
+} else {
+$6=$7;
+};
+$4=_st($5).__comma($6);
+value=_st($3)._eval_on_($4,self["@session"]);
+value;
+return _st(aBlock)._value_value_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({name:name,expr:expr,varName:varName,value:value},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"assignNewVariable:do:",{buffer:buffer,aBlock:aBlock},smalltalk.Repl)})},
+args: ["buffer", "aBlock"],
+source: "assignNewVariable: buffer do: aBlock\x0a\x09\x22Assigns a new variable and calls the given block with the variable's name and value\x0a\x09 if buffer contains an assignment expression. If it doesn't the block is called with nil for\x0a\x09 both arguments.\x22\x0a\x09^ self parseAssignment: buffer do: [ :name :expr || varName value |\x0a\x09\x09varName := name ifNil: [self nextResultName].\x0a\x09\x09session := self addVariableNamed: varName to: session.\x0a\x09\x09value := self eval: varName, ' := ', (expr ifNil: [buffer]) on: session.\x0a\x09\x09aBlock value: varName value: value]",
+messageSends: ["parseAssignment:do:", "ifNil:", "nextResultName", "addVariableNamed:to:", "eval:on:", ",", "value:value:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "clearScreen",
+category: 'private',
+fn: function (){
+var self=this;
+var esc,cls;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+esc=_st($String())._fromCharCode_((27));
+cls=_st(_st(_st(esc).__comma("[2J")).__comma(esc)).__comma("[0;0f");
+_st(_st(process)._stdout())._write_(cls);
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"clearScreen",{esc:esc,cls:cls},smalltalk.Repl)})},
+args: [],
+source: "clearScreen\x0a\x09| esc cls |\x0a\x09esc := String fromCharCode: 27.\x0a\x09cls := esc, '[2J', esc, '[0;0f'.\x0a\x09process stdout write: cls.\x0a\x09interface prompt",
+messageSends: ["fromCharCode:", ",", "write:", "stdout", "prompt"],
+referencedClasses: ["String"]
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "close",
@@ -1134,6 +1220,24 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commands",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@commands"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commands",{},smalltalk.Repl)})},
+args: [],
+source: "commands\x0a\x09^ commands",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "createInterface",
@@ -1141,44 +1245,85 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 self["@interface"]=_st(self["@readline"])._createInterface_stdout_(_st(process)._stdin(),_st(process)._stdout());
 _st(self["@interface"])._on_do_("line",(function(buffer){
 return smalltalk.withContext(function($ctx2) {
-return self._eval_(buffer);
+return self._processLine_(buffer);
 }, function($ctx2) {$ctx2.fillBlock({buffer:buffer},$ctx1)})}));
 _st(self["@interface"])._on_do_("close",(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._close();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-self._setPrompt();
+$1=self;
+_st($1)._printWelcome();
+_st($1)._setupHotkeys();
+$2=_st($1)._setPrompt();
 _st(self["@interface"])._prompt();
 return self}, function($ctx1) {$ctx1.fill(self,"createInterface",{},smalltalk.Repl)})},
 args: [],
-source: "createInterface\x0a\x09\x22No completion for now\x22\x0a\x09interface := readline createInterface: process stdin stdout: process stdout.\x0a\x09interface on: 'line' do: [:buffer  | self eval: buffer].\x0a\x09interface on: 'close' do: [self close].\x0a\x09self setPrompt.\x0a\x09interface prompt",
-messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"],
+source: "createInterface\x0a\x09interface := readline createInterface: process stdin stdout: process stdout.\x0a\x09interface on: 'line' do: [:buffer | self processLine: buffer].\x0a\x09interface on: 'close' do: [self close].\x0a\x09self printWelcome; setupHotkeys; setPrompt.\x0a\x09interface prompt",
+messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "processLine:", "close", "printWelcome", "setupHotkeys", "setPrompt", "prompt"],
 referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "encapsulateVariable:withValue:in:",
+category: 'private',
+fn: function (aString,anObject,aClass){
+var self=this;
+var compiler;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+compiler=_st($Compiler())._new();
+_st(compiler)._install_forClass_category_(_st(_st(_st(aString).__comma(": anObject ^ ")).__comma(aString)).__comma(" := anObject"),aClass,"session");
+_st(compiler)._install_forClass_category_(_st(_st(aString).__comma(" ^ ")).__comma(aString),aClass,"session");
+return self}, function($ctx1) {$ctx1.fill(self,"encapsulateVariable:withValue:in:",{aString:aString,anObject:anObject,aClass:aClass,compiler:compiler},smalltalk.Repl)})},
+args: ["aString", "anObject", "aClass"],
+source: "encapsulateVariable: aString withValue: anObject in: aClass\x0a\x09\x22Add getter and setter for given variable to session.\x22\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09compiler install: aString, ': anObject ^ ', aString, ' := anObject' forClass: aClass category: 'session'.\x0a\x09compiler install: aString, ' ^ ', aString forClass: aClass category: 'session'.",
+messageSends: ["new", "install:forClass:category:", ","],
+referencedClasses: ["Compiler"]
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "eval:",
 category: 'actions',
 fn: function (buffer){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._eval_on_(buffer,_st($DoIt())._new());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer},smalltalk.Repl)})},
+args: ["buffer"],
+source: "eval: buffer\x0a\x09^ self eval: buffer on: DoIt new.",
+messageSends: ["eval:on:", "new"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "eval:on:",
+category: 'actions',
+fn: function (buffer,anObject){
+var self=this;
 var result;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
 function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3;
 $1=_st(buffer)._isEmpty();
 if(! smalltalk.assert($1)){
 self._try_catch_((function(){
 return smalltalk.withContext(function($ctx2) {
-result=_st(_st($Compiler())._new())._evaluateExpression_(buffer);
-result;
-return _st($Transcript())._show_(result);
+result=_st(_st($Compiler())._new())._evaluateExpression_on_(buffer,anObject);
+return result;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(function(e){
 return smalltalk.withContext(function($ctx2) {
 $2=_st(e)._isSmalltalkError();
@@ -1189,12 +1334,42 @@ return _st(_st(process)._stdout())._write_(_st(e)._jsStack());
 };
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 };
-_st(self["@interface"])._prompt();
-return self}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer,result:result},smalltalk.Repl)})},
-args: ["buffer"],
-source: "eval: buffer\x0a\x09| result |\x0a\x09buffer isEmpty ifFalse: [\x0a\x09\x09self try: [\x0a\x09\x09\x09result := Compiler new evaluateExpression: buffer.\x0a\x09\x09\x09Transcript show: result]\x0a\x09\x09catch: [:e |\x0a\x09\x09\x09e isSmalltalkError\x0a\x09\x09\x09    ifTrue: [ErrorHandler new handleError: e]\x0a\x09\x09\x09    ifFalse: [process stdout write: e jsStack]]].\x0a\x09interface prompt",
-messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:", "new", "show:", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty", "prompt"],
-referencedClasses: ["Compiler", "Transcript", "ErrorHandler"]
+$3=result;
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:on:",{buffer:buffer,anObject:anObject,result:result},smalltalk.Repl)})},
+args: ["buffer", "anObject"],
+source: "eval: buffer on: anObject\x0a\x09| result |\x0a\x09buffer isEmpty ifFalse: [\x0a\x09\x09self try: [\x0a\x09\x09\x09result := Compiler new evaluateExpression: buffer on: anObject]\x0a\x09\x09catch: [:e |\x0a\x09\x09\x09e isSmalltalkError\x0a\x09\x09\x09    ifTrue: [ErrorHandler new handleError: e]\x0a\x09\x09\x09    ifFalse: [process stdout write: e jsStack]]].\x0a\x09^ result",
+messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:on:", "new", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty"],
+referencedClasses: ["Compiler", "ErrorHandler"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "executeCommand:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+_st(self._commands())._keysAndValuesDo_((function(names,cmd){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(names)._includes_(aString);
+if(smalltalk.assert($1)){
+_st(cmd)._value();
+throw $early=[true];
+};
+}, function($ctx2) {$ctx2.fillBlock({names:names,cmd:cmd},$ctx1)})}));
+return false;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"executeCommand:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "executeCommand: aString\x0a\x09\x22Tries to process the given string as a command. Returns true if it was a command, false if not.\x22\x0a\x09self commands keysAndValuesDo: [:names :cmd |\x0a\x09\x09(names includes: aString) ifTrue: [\x0a\x09\x09\x09cmd value.\x0a\x09\x09\x09^ true]].\x0a\x09^ false",
+messageSends: ["keysAndValuesDo:", "ifTrue:", "value", "includes:", "commands"],
+referencedClasses: []
 }),
 smalltalk.Repl);
 
@@ -1204,14 +1379,227 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
 return smalltalk.withContext(function($ctx1) { 
 smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@session"]=_st($DoIt())._new();
 self["@readline"]=_st(require)._value_("readline");
 self["@util"]=_st(require)._value_("util");
+self._setupCommands();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Repl)})},
 args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09readline := require value: 'readline'.\x0a\x09util := require value: 'util'",
-messageSends: ["initialize", "value:"],
+source: "initialize\x0a\x09super initialize.\x0a\x09session := DoIt new.\x0a\x09readline := require value: 'readline'.\x0a\x09util := require value: 'util'.\x0a\x09self setupCommands",
+messageSends: ["initialize", "new", "value:", "setupCommands"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "instanceVariableNamesFor:",
+category: 'private',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(aClass)._superclass();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(aClass)._instanceVariableNames();
+} else {
+$1=_st(_st(aClass)._instanceVariableNames())._copyWithAll_(self._instanceVariableNamesFor_(_st(aClass)._superclass()));
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"instanceVariableNamesFor:",{aClass:aClass},smalltalk.Repl)})},
+args: ["aClass"],
+source: "instanceVariableNamesFor: aClass\x0a\x09\x22Yields all instance variable names for the given class, including inherited ones.\x22\x0a\x09^ aClass superclass\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09aClass instanceVariableNames copyWithAll: (self instanceVariableNamesFor: aClass superclass)]\x0a\x09\x09ifNil: [\x0a\x09\x09\x09aClass instanceVariableNames]",
+messageSends: ["ifNotNil:ifNil:", "copyWithAll:", "instanceVariableNamesFor:", "superclass", "instanceVariableNames"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isIdentifier:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(aString)._match_("^[a-z_]\x5cw+$"._asRegexp());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isIdentifier:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "isIdentifier: aString\x0a\x09^ aString match: '^[a-z_]\x5cw+$' asRegexp",
+messageSends: ["match:", "asRegexp"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isVariableDefined:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._instanceVariableNamesFor_(_st(self["@session"])._class()))._includes_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isVariableDefined:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "isVariableDefined: aString\x0a\x09^ (self instanceVariableNamesFor: session class) includes: aString",
+messageSends: ["includes:", "instanceVariableNamesFor:", "class"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "nextResultName",
+category: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self["@resultCount"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@resultCount"]=(1);
+} else {
+self["@resultCount"]=_st(self["@resultCount"]).__plus((1));
+};
+$2="res".__comma(_st(self["@resultCount"])._asString());
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"nextResultName",{},smalltalk.Repl)})},
+args: [],
+source: "nextResultName\x0a\x09resultCount := resultCount\x0a    \x09ifNotNil: [resultCount + 1]\x0a    \x09ifNil: [1].\x0a    ^ 'res', resultCount asString",
+messageSends: ["ifNotNil:ifNil:", "+", ",", "asString"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onKeyPress:",
+category: 'private',
+fn: function (key){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(key)._ctrl())._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(key)._name()).__eq("l");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
+self._clearScreen();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"onKeyPress:",{key:key},smalltalk.Repl)})},
+args: ["key"],
+source: "onKeyPress: key\x0a\x09(key ctrl and: [key name = 'l'])\x0a\x09\x09ifTrue: [self clearScreen]",
+messageSends: ["ifTrue:", "clearScreen", "and:", "=", "name", "ctrl"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "parseAssignment:do:",
+category: 'private',
+fn: function (aString,aBlock){
+var self=this;
+var assignment;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+assignment=_st(_st(aString)._tokenize_(":="))._collect_((function(s){
+return smalltalk.withContext(function($ctx2) {
+return _st(s)._trimBoth();
+}, function($ctx2) {$ctx2.fillBlock({s:s},$ctx1)})}));
+$2=_st(_st(_st(assignment)._size()).__eq((2)))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._isIdentifier_(_st(assignment)._first());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value_value_(_st(assignment)._first(),_st(assignment)._last());
+} else {
+$1=_st(aBlock)._value_value_(nil,nil);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"parseAssignment:do:",{aString:aString,aBlock:aBlock,assignment:assignment},smalltalk.Repl)})},
+args: ["aString", "aBlock"],
+source: "parseAssignment: aString do: aBlock\x0a\x09\x22Assigns a new variable if the given string is an assignment expression. Calls the given block with name and value.\x0a\x09 If the string is not one no variable will be assigned and the block will be called with nil for both arguments.\x22\x0a\x09| assignment |\x0a\x09assignment := (aString tokenize: ':=') collect: [:s | s trimBoth].\x0a\x09^ (assignment size = 2 and: [self isIdentifier: assignment first])\x0a\x09\x09ifTrue: [aBlock value: assignment first value: assignment last]\x0a\x09\x09ifFalse: [aBlock value: nil value: nil]",
+messageSends: ["collect:", "trimBoth", "tokenize:", "ifTrue:ifFalse:", "value:value:", "first", "last", "and:", "isIdentifier:", "=", "size"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "presentResultNamed:withValue:",
+category: 'private',
+fn: function (varName,value){
+var self=this;
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=$Transcript();
+_st($1)._show_(_st(_st(_st(_st(varName).__comma(": ")).__comma(_st(_st(value)._class())._name())).__comma(" = ")).__comma(_st(value)._asString()));
+$2=_st($1)._cr();
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"presentResultNamed:withValue:",{varName:varName,value:value},smalltalk.Repl)})},
+args: ["varName", "value"],
+source: "presentResultNamed: varName withValue: value\x0a\x09Transcript show: varName, ': ', value class name, ' = ', value asString; cr.\x0a\x09interface prompt",
+messageSends: ["show:", ",", "asString", "name", "class", "cr", "prompt"],
+referencedClasses: ["Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "printWelcome",
+category: 'private',
+fn: function (){
+var self=this;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st($Transcript())._show_(_st(_st(_st("Welcome to Amber version ".__comma(_st(_st($Smalltalk())._current())._version())).__comma(" (NodeJS ")).__comma(_st(_st(process)._versions())._node())).__comma(")."));
+$1=$Transcript();
+_st($1)._show_("Type :q to exit.");
+$2=_st($1)._cr();
+return self}, function($ctx1) {$ctx1.fill(self,"printWelcome",{},smalltalk.Repl)})},
+args: [],
+source: "printWelcome\x0a\x09Transcript show: 'Welcome to Amber version ', Smalltalk current version, ' (NodeJS ', process versions node, ').'.\x0a\x09Transcript show: 'Type :q to exit.'; cr.",
+messageSends: ["show:", ",", "node", "versions", "version", "current", "cr"],
+referencedClasses: ["Smalltalk", "Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "processLine:",
+category: 'private',
+fn: function (buffer){
+var self=this;
+var show;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+show=(function(varName,value){
+return smalltalk.withContext(function($ctx2) {
+return self._presentResultNamed_withValue_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({varName:varName,value:value},$ctx1)})});
+$1=self._executeCommand_(buffer);
+if(! smalltalk.assert($1)){
+$2=self._isVariableDefined_(buffer);
+if(smalltalk.assert($2)){
+_st(show)._value_value_(buffer,_st(self["@session"])._perform_(buffer));
+} else {
+self._assignNewVariable_do_(buffer,show);
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"processLine:",{buffer:buffer,show:show},smalltalk.Repl)})},
+args: ["buffer"],
+source: "processLine: buffer\x0a\x09\x22Processes lines entered through the readline interface.\x22\x0a\x09| show |\x0a\x09show := [:varName :value | self presentResultNamed: varName withValue: value].\x0a\x09(self executeCommand: buffer) ifFalse: [\x0a\x09\x09(self isVariableDefined: buffer)\x0a\x09\x09\x09ifTrue: [show value: buffer value: (session perform: buffer)]\x0a\x09\x09\x09ifFalse: [self assignNewVariable: buffer do: show]]",
+messageSends: ["presentResultNamed:withValue:", "ifFalse:", "ifTrue:ifFalse:", "value:value:", "perform:", "assignNewVariable:do:", "isVariableDefined:", "executeCommand:"],
 referencedClasses: []
 }),
 smalltalk.Repl);
@@ -1232,6 +1620,25 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setPreviousVariablesFor:from:",
+category: 'private',
+fn: function (newObject,oldObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._instanceVariableNamesFor_(_st(oldObject)._class()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newObject)._perform_withArguments_(_st(each).__comma(":"),[_st(oldObject)._perform_(each)]);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setPreviousVariablesFor:from:",{newObject:newObject,oldObject:oldObject},smalltalk.Repl)})},
+args: ["newObject", "oldObject"],
+source: "setPreviousVariablesFor: newObject from: oldObject\x0a\x09(self instanceVariableNamesFor: oldObject class) do: [:each |\x0a\x09\x09newObject perform: each, ':' withArguments: {oldObject perform: each}].",
+messageSends: ["do:", "perform:withArguments:", ",", "perform:", "instanceVariableNamesFor:", "class"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setPrompt",
@@ -1248,6 +1655,99 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupCommands",
+category: 'initialization',
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+self["@commands"]=_st($Dictionary())._from_([_st([":q"]).__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(process)._exit();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})),_st([""]).__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@interface"])._prompt();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
+return self}, function($ctx1) {$ctx1.fill(self,"setupCommands",{},smalltalk.Repl)})},
+args: [],
+source: "setupCommands\x0a\x09commands := Dictionary from: {\x0a\x09\x09{':q'} -> [process exit].\x0a\x09\x09{''} -> [interface prompt]}",
+messageSends: ["from:", "->", "exit", "prompt"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupHotkeys",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(_st(process)._stdin())._on_do_("keypress",(function(s,key){
+return smalltalk.withContext(function($ctx2) {
+$1=key;
+if(($receiver = $1) == nil || $receiver == undefined){
+return $1;
+} else {
+return self._onKeyPress_(key);
+};
+}, function($ctx2) {$ctx2.fillBlock({s:s,key:key},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setupHotkeys",{},smalltalk.Repl)})},
+args: [],
+source: "setupHotkeys\x0a\x09process stdin on: 'keypress' do: [:s :key | key ifNotNil: [self onKeyPress: key]].",
+messageSends: ["on:do:", "ifNotNil:", "onKeyPress:", "stdin"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclass:withVariable:",
+category: 'private',
+fn: function (aClass,varName){
+var self=this;
+function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st($ClassBuilder())._new())._addSubclassOf_named_instanceVariableNames_package_(aClass,_st(self._subclassNameFor_(aClass))._asSymbol(),[varName],"Compiler-Core");
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclass:withVariable:",{aClass:aClass,varName:varName},smalltalk.Repl)})},
+args: ["aClass", "varName"],
+source: "subclass: aClass withVariable: varName\x0a\x09\x22Create subclass with new variable.\x22\x0a\x09^ ClassBuilder new\x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: (self subclassNameFor: aClass) asSymbol\x0a\x09\x09instanceVariableNames: {varName}\x0a\x09\x09package: 'Compiler-Core'",
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "asSymbol", "subclassNameFor:", "new"],
+referencedClasses: ["ClassBuilder"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclassNameFor:",
+category: 'private',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(_st(aClass)._name())._matchesOf_("\x5cd+$");
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(_st(aClass)._name()).__comma("2");
+} else {
+var counter;
+counter=_st(_st(_st(_st(_st(aClass)._name())._matchesOf_("\x5cd+$"))._first())._asNumber()).__plus((1));
+counter;
+$1=_st(_st(aClass)._name())._replaceRegexp_with_("\x5cd+$"._asRegexp(),_st(counter)._asString());
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclassNameFor:",{aClass:aClass},smalltalk.Repl)})},
+args: ["aClass"],
+source: "subclassNameFor: aClass\x0a\x09^ (aClass name matchesOf: '\x5cd+$')\x0a\x09\x09ifNotNil: [ | counter |\x0a\x09\x09\x09counter := (aClass name matchesOf: '\x5cd+$') first asNumber + 1.\x0a\x09\x09\x09aClass name replaceRegexp: '\x5cd+$' asRegexp with: counter asString]\x0a\x09\x09ifNil: [\x0a\x09\x09\x09aClass name, '2'].",
+messageSends: ["ifNotNil:ifNil:", "+", "asNumber", "first", "matchesOf:", "name", "replaceRegexp:with:", "asRegexp", "asString", ","],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 
 smalltalk.addMethod(
 smalltalk.method({

+ 585 - 26
cli/js/amber-cli.js

@@ -128,6 +128,8 @@ function Smalltalk() {
 		'implements', 'interface', 'let', 'package', 'private', 'protected',
 		'public', 'static', 'yield'];
 
+	st.globalJsVariables = ['jQuery', 'window', 'document', 'process', 'global'];
+
 	var initialized = false;
 
 	/* Smalltalk classes */
@@ -5964,6 +5966,25 @@ smalltalk.Random);
 
 smalltalk.addClass('Smalltalk', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.Smalltalk.comment="I represent the global JavaScript variable `smalltalk` declared in `js/boot.js`.\x0a\x0a## API\x0a\x0aI have only one instance, accessed with class-side method `#current`.\x0a\x0aThe `smalltalk` object holds all class and packages defined in the system.\x0a\x0a## Classes\x0a\x0aClasses can be accessed using the following methods:\x0a\x0a- `#classes` answers the full list of Smalltalk classes in the system\x0a- `#at:` answers a specific class or `nil`\x0a\x0a## Packages\x0a\x0aPackages can be accessed using the following methods:\x0a\x0a- `#packages` answers the full list of packages\x0a- `#packageAt:` answers a specific package or `nil`\x0a\x0a## Parsing\x0a\x0aThe `#parse:` method is used to parse Amber source code.\x0aIt requires the `Compiler` package and the `js/parser.js` parser file in order to work.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addGlobalJsVariable:",
+category: 'globals',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(self._globalJsVariables())._add_(aString);
+$1=self;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"addGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+args: ["aString"],
+source: "addGlobalJsVariable: aString\x0a\x09self globalJsVariables add: aString.\x0a\x09^self",
+messageSends: ["add:", "globalJsVariables"],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asSmalltalkException:",
@@ -6095,6 +6116,27 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deleteGlobalJsVariable:",
+category: 'globals',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(self._globalJsVariables())._remove_ifAbsent_(aString,(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$1=self;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"deleteGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+args: ["aString"],
+source: "deleteGlobalJsVariable: aString\x0a\x09self globalJsVariables remove: aString ifAbsent:[].\x0a\x09^self",
+messageSends: ["remove:ifAbsent:", "globalJsVariables"],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "deletePackage:",
@@ -6111,6 +6153,22 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "globalJsVariables",
+category: 'globals',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.globalJsVariables;
+return self}, function($ctx1) {$ctx1.fill(self,"globalJsVariables",{},smalltalk.Smalltalk)})},
+args: [],
+source: "globalJsVariables\x0a\x09\x22Array of global JavaScript variables\x22\x0a\x09<return self.globalJsVariables>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isSmalltalkObject:",
@@ -13519,7 +13577,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 
 		for(var i=0;i<self.length;i++) {
-			if(self[i] == anObject) {
+			if(_st(self[i]).__eq(anObject)) {
 				self.splice(i,1);
 				return self;
 			}
@@ -13528,7 +13586,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"remove:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.Array)})},
 args: ["anObject", "aBlock"],
-source: "remove: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09for(var i=0;i<self.length;i++) {\x0a\x09\x09\x09if(self[i] == anObject) {\x0a\x09\x09\x09\x09self.splice(i,1);\x0a\x09\x09\x09\x09return self;\x0a\x09\x09\x09}\x0a\x09\x09};\x0a\x09\x09aBlock._value();\x0a\x09>",
+source: "remove: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09for(var i=0;i<self.length;i++) {\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {\x0a\x09\x09\x09\x09self.splice(i,1);\x0a\x09\x09\x09\x09return self;\x0a\x09\x09\x09}\x0a\x09\x09};\x0a\x09\x09aBlock._value();\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -15237,7 +15295,7 @@ return smalltalk.withContext(function($ctx1) {
 
 		var found;
 		for(var i=0; i < self['@elements'].length; i++) {
-			if(anObject == self['@elements'][i]) {
+			if(_st(anObject).__eq(self['@elements'][i])) {
 				found = true;
 				break;
 			}
@@ -15246,7 +15304,7 @@ return smalltalk.withContext(function($ctx1) {
 	;
 return self}, function($ctx1) {$ctx1.fill(self,"add:",{anObject:anObject},smalltalk.Set)})},
 args: ["anObject"],
-source: "add: anObject\x0a\x09<\x0a\x09\x09var found;\x0a\x09\x09for(var i=0; i < self['@elements'].length; i++) {\x0a\x09\x09\x09if(anObject == self['@elements'][i]) {\x0a\x09\x09\x09\x09found = true;\x0a\x09\x09\x09\x09break;\x0a\x09\x09\x09}\x0a\x09\x09}\x0a\x09\x09if(!found) {self['@elements'].push(anObject)}\x0a\x09>",
+source: "add: anObject\x0a\x09<\x0a\x09\x09var found;\x0a\x09\x09for(var i=0; i < self['@elements'].length; i++) {\x0a\x09\x09\x09if(_st(anObject).__eq(self['@elements'][i])) {\x0a\x09\x09\x09\x09found = true;\x0a\x09\x09\x09\x09break;\x0a\x09\x09\x09}\x0a\x09\x09}\x0a\x09\x09if(!found) {self['@elements'].push(anObject)}\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -27716,10 +27774,11 @@ fn: function (aNode){
 var self=this;
 var identifier;
 function $UnknownVariableError(){return smalltalk.UnknownVariableError||(typeof UnknownVariableError=="undefined"?nil:UnknownVariableError)}
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
 identifier=_st(aNode)._value();
-$1=_st(_st(["jQuery", "window", "document", "process", "global"]._includes_(identifier))._not())._and_((function(){
+$1=_st(_st(_st(_st(_st($Smalltalk())._current())._globalJsVariables())._includes_(identifier))._not())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._isVariableGloballyUndefined_(identifier);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
@@ -27733,9 +27792,9 @@ _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_s
 };
 return self}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
-source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow four variable names in addition: `jQuery`, `window`, `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09\x0a\x09((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not\x0a\x09\x09and: [ self isVariableGloballyUndefined: identifier ])\x0a\x09\x09\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:"],
-referencedClasses: ["UnknownVariableError"]
+source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow all variables listed by Smalltalk>>#globalJsVariables.\x0a\x09This list includes: `jQuery`, `window`, `document`,  `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09\x0a\x09((Smalltalk current globalJsVariables includes: identifier) not\x0a\x09\x09and: [ self isVariableGloballyUndefined: identifier ])\x0a\x09\x09\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:", "globalJsVariables", "current"],
+referencedClasses: ["UnknownVariableError", "Smalltalk"]
 }),
 smalltalk.SemanticAnalyzer);
 
@@ -35571,8 +35630,94 @@ referencedClasses: []
 smalltalk.FileServer.klass);
 
 
-smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util'], 'AmberCli');
+smalltalk.addClass('Repl', smalltalk.Object, ['readline', 'interface', 'util', 'session', 'resultCount', 'commands'], 'AmberCli');
 smalltalk.Repl.comment="I am a class representing a REPL (Read Evaluate Print Loop) and provide a command line interface to Amber Smalltalk.\x0aOn the prompt you can type Amber statements which will be evaluated after pressing <Enter>.\x0aThe evaluation is comparable with executing a 'DoIt' in a workspace.\x0a\x0aMy runtime requirement is a functional Node.js executable with working Readline support.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addVariableNamed:to:",
+category: 'private',
+fn: function (aString,anObject){
+var self=this;
+var newClass,newObject;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+newClass=self._subclass_withVariable_(_st(anObject)._class(),aString);
+self._encapsulateVariable_withValue_in_(aString,anObject,newClass);
+newObject=_st(newClass)._new();
+self._setPreviousVariablesFor_from_(newObject,anObject);
+$1=newObject;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"addVariableNamed:to:",{aString:aString,anObject:anObject,newClass:newClass,newObject:newObject},smalltalk.Repl)})},
+args: ["aString", "anObject"],
+source: "addVariableNamed: aString to: anObject\x0a\x09| newClass newObject |\x0a\x09newClass := self subclass: anObject class withVariable: aString.\x0a\x09self encapsulateVariable: aString withValue: anObject in: newClass.\x0a\x09newObject := newClass new.\x0a\x09self setPreviousVariablesFor: newObject from: anObject.\x0a\x09^ newObject",
+messageSends: ["subclass:withVariable:", "class", "encapsulateVariable:withValue:in:", "new", "setPreviousVariablesFor:from:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "assignNewVariable:do:",
+category: 'private',
+fn: function (buffer,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$5,$7,$6,$4,$1;
+$1=self._parseAssignment_do_(buffer,(function(name,expr){
+var varName,value;
+return smalltalk.withContext(function($ctx2) {
+$2=name;
+if(($receiver = $2) == nil || $receiver == undefined){
+varName=self._nextResultName();
+} else {
+varName=$2;
+};
+varName;
+self["@session"]=self._addVariableNamed_to_(varName,self["@session"]);
+self["@session"];
+$3=self;
+$5=_st(varName).__comma(" := ");
+$7=expr;
+if(($receiver = $7) == nil || $receiver == undefined){
+$6=buffer;
+} else {
+$6=$7;
+};
+$4=_st($5).__comma($6);
+value=_st($3)._eval_on_($4,self["@session"]);
+value;
+return _st(aBlock)._value_value_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({name:name,expr:expr,varName:varName,value:value},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"assignNewVariable:do:",{buffer:buffer,aBlock:aBlock},smalltalk.Repl)})},
+args: ["buffer", "aBlock"],
+source: "assignNewVariable: buffer do: aBlock\x0a\x09\x22Assigns a new variable and calls the given block with the variable's name and value\x0a\x09 if buffer contains an assignment expression. If it doesn't the block is called with nil for\x0a\x09 both arguments.\x22\x0a\x09^ self parseAssignment: buffer do: [ :name :expr || varName value |\x0a\x09\x09varName := name ifNil: [self nextResultName].\x0a\x09\x09session := self addVariableNamed: varName to: session.\x0a\x09\x09value := self eval: varName, ' := ', (expr ifNil: [buffer]) on: session.\x0a\x09\x09aBlock value: varName value: value]",
+messageSends: ["parseAssignment:do:", "ifNil:", "nextResultName", "addVariableNamed:to:", "eval:on:", ",", "value:value:"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "clearScreen",
+category: 'private',
+fn: function (){
+var self=this;
+var esc,cls;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+esc=_st($String())._fromCharCode_((27));
+cls=_st(_st(_st(esc).__comma("[2J")).__comma(esc)).__comma("[0;0f");
+_st(_st(process)._stdout())._write_(cls);
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"clearScreen",{esc:esc,cls:cls},smalltalk.Repl)})},
+args: [],
+source: "clearScreen\x0a\x09| esc cls |\x0a\x09esc := String fromCharCode: 27.\x0a\x09cls := esc, '[2J', esc, '[0;0f'.\x0a\x09process stdout write: cls.\x0a\x09interface prompt",
+messageSends: ["fromCharCode:", ",", "write:", "stdout", "prompt"],
+referencedClasses: ["String"]
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "close",
@@ -35589,6 +35734,24 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "commands",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@commands"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"commands",{},smalltalk.Repl)})},
+args: [],
+source: "commands\x0a\x09^ commands",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "createInterface",
@@ -35596,44 +35759,85 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 self["@interface"]=_st(self["@readline"])._createInterface_stdout_(_st(process)._stdin(),_st(process)._stdout());
 _st(self["@interface"])._on_do_("line",(function(buffer){
 return smalltalk.withContext(function($ctx2) {
-return self._eval_(buffer);
+return self._processLine_(buffer);
 }, function($ctx2) {$ctx2.fillBlock({buffer:buffer},$ctx1)})}));
 _st(self["@interface"])._on_do_("close",(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._close();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-self._setPrompt();
+$1=self;
+_st($1)._printWelcome();
+_st($1)._setupHotkeys();
+$2=_st($1)._setPrompt();
 _st(self["@interface"])._prompt();
 return self}, function($ctx1) {$ctx1.fill(self,"createInterface",{},smalltalk.Repl)})},
 args: [],
-source: "createInterface\x0a\x09\x22No completion for now\x22\x0a\x09interface := readline createInterface: process stdin stdout: process stdout.\x0a\x09interface on: 'line' do: [:buffer  | self eval: buffer].\x0a\x09interface on: 'close' do: [self close].\x0a\x09self setPrompt.\x0a\x09interface prompt",
-messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "eval:", "close", "setPrompt", "prompt"],
+source: "createInterface\x0a\x09interface := readline createInterface: process stdin stdout: process stdout.\x0a\x09interface on: 'line' do: [:buffer | self processLine: buffer].\x0a\x09interface on: 'close' do: [self close].\x0a\x09self printWelcome; setupHotkeys; setPrompt.\x0a\x09interface prompt",
+messageSends: ["createInterface:stdout:", "stdin", "stdout", "on:do:", "processLine:", "close", "printWelcome", "setupHotkeys", "setPrompt", "prompt"],
 referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "encapsulateVariable:withValue:in:",
+category: 'private',
+fn: function (aString,anObject,aClass){
+var self=this;
+var compiler;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+compiler=_st($Compiler())._new();
+_st(compiler)._install_forClass_category_(_st(_st(_st(aString).__comma(": anObject ^ ")).__comma(aString)).__comma(" := anObject"),aClass,"session");
+_st(compiler)._install_forClass_category_(_st(_st(aString).__comma(" ^ ")).__comma(aString),aClass,"session");
+return self}, function($ctx1) {$ctx1.fill(self,"encapsulateVariable:withValue:in:",{aString:aString,anObject:anObject,aClass:aClass,compiler:compiler},smalltalk.Repl)})},
+args: ["aString", "anObject", "aClass"],
+source: "encapsulateVariable: aString withValue: anObject in: aClass\x0a\x09\x22Add getter and setter for given variable to session.\x22\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09compiler install: aString, ': anObject ^ ', aString, ' := anObject' forClass: aClass category: 'session'.\x0a\x09compiler install: aString, ' ^ ', aString forClass: aClass category: 'session'.",
+messageSends: ["new", "install:forClass:category:", ","],
+referencedClasses: ["Compiler"]
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "eval:",
 category: 'actions',
 fn: function (buffer){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._eval_on_(buffer,_st($DoIt())._new());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer},smalltalk.Repl)})},
+args: ["buffer"],
+source: "eval: buffer\x0a\x09^ self eval: buffer on: DoIt new.",
+messageSends: ["eval:on:", "new"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "eval:on:",
+category: 'actions',
+fn: function (buffer,anObject){
+var self=this;
 var result;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
 function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3;
 $1=_st(buffer)._isEmpty();
 if(! smalltalk.assert($1)){
 self._try_catch_((function(){
 return smalltalk.withContext(function($ctx2) {
-result=_st(_st($Compiler())._new())._evaluateExpression_(buffer);
-result;
-return _st($Transcript())._show_(result);
+result=_st(_st($Compiler())._new())._evaluateExpression_on_(buffer,anObject);
+return result;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),(function(e){
 return smalltalk.withContext(function($ctx2) {
 $2=_st(e)._isSmalltalkError();
@@ -35644,12 +35848,42 @@ return _st(_st(process)._stdout())._write_(_st(e)._jsStack());
 };
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 };
-_st(self["@interface"])._prompt();
-return self}, function($ctx1) {$ctx1.fill(self,"eval:",{buffer:buffer,result:result},smalltalk.Repl)})},
-args: ["buffer"],
-source: "eval: buffer\x0a\x09| result |\x0a\x09buffer isEmpty ifFalse: [\x0a\x09\x09self try: [\x0a\x09\x09\x09result := Compiler new evaluateExpression: buffer.\x0a\x09\x09\x09Transcript show: result]\x0a\x09\x09catch: [:e |\x0a\x09\x09\x09e isSmalltalkError\x0a\x09\x09\x09    ifTrue: [ErrorHandler new handleError: e]\x0a\x09\x09\x09    ifFalse: [process stdout write: e jsStack]]].\x0a\x09interface prompt",
-messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:", "new", "show:", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty", "prompt"],
-referencedClasses: ["Compiler", "Transcript", "ErrorHandler"]
+$3=result;
+return $3;
+}, function($ctx1) {$ctx1.fill(self,"eval:on:",{buffer:buffer,anObject:anObject,result:result},smalltalk.Repl)})},
+args: ["buffer", "anObject"],
+source: "eval: buffer on: anObject\x0a\x09| result |\x0a\x09buffer isEmpty ifFalse: [\x0a\x09\x09self try: [\x0a\x09\x09\x09result := Compiler new evaluateExpression: buffer on: anObject]\x0a\x09\x09catch: [:e |\x0a\x09\x09\x09e isSmalltalkError\x0a\x09\x09\x09    ifTrue: [ErrorHandler new handleError: e]\x0a\x09\x09\x09    ifFalse: [process stdout write: e jsStack]]].\x0a\x09^ result",
+messageSends: ["ifFalse:", "try:catch:", "evaluateExpression:on:", "new", "ifTrue:ifFalse:", "handleError:", "write:", "jsStack", "stdout", "isSmalltalkError", "isEmpty"],
+referencedClasses: ["Compiler", "ErrorHandler"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "executeCommand:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+_st(self._commands())._keysAndValuesDo_((function(names,cmd){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(names)._includes_(aString);
+if(smalltalk.assert($1)){
+_st(cmd)._value();
+throw $early=[true];
+};
+}, function($ctx2) {$ctx2.fillBlock({names:names,cmd:cmd},$ctx1)})}));
+return false;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"executeCommand:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "executeCommand: aString\x0a\x09\x22Tries to process the given string as a command. Returns true if it was a command, false if not.\x22\x0a\x09self commands keysAndValuesDo: [:names :cmd |\x0a\x09\x09(names includes: aString) ifTrue: [\x0a\x09\x09\x09cmd value.\x0a\x09\x09\x09^ true]].\x0a\x09^ false",
+messageSends: ["keysAndValuesDo:", "ifTrue:", "value", "includes:", "commands"],
+referencedClasses: []
 }),
 smalltalk.Repl);
 
@@ -35659,14 +35893,227 @@ selector: "initialize",
 category: 'initialization',
 fn: function (){
 var self=this;
+function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
 return smalltalk.withContext(function($ctx1) { 
 smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@session"]=_st($DoIt())._new();
 self["@readline"]=_st(require)._value_("readline");
 self["@util"]=_st(require)._value_("util");
+self._setupCommands();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Repl)})},
 args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09readline := require value: 'readline'.\x0a\x09util := require value: 'util'",
-messageSends: ["initialize", "value:"],
+source: "initialize\x0a\x09super initialize.\x0a\x09session := DoIt new.\x0a\x09readline := require value: 'readline'.\x0a\x09util := require value: 'util'.\x0a\x09self setupCommands",
+messageSends: ["initialize", "new", "value:", "setupCommands"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "instanceVariableNamesFor:",
+category: 'private',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(aClass)._superclass();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(aClass)._instanceVariableNames();
+} else {
+$1=_st(_st(aClass)._instanceVariableNames())._copyWithAll_(self._instanceVariableNamesFor_(_st(aClass)._superclass()));
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"instanceVariableNamesFor:",{aClass:aClass},smalltalk.Repl)})},
+args: ["aClass"],
+source: "instanceVariableNamesFor: aClass\x0a\x09\x22Yields all instance variable names for the given class, including inherited ones.\x22\x0a\x09^ aClass superclass\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09aClass instanceVariableNames copyWithAll: (self instanceVariableNamesFor: aClass superclass)]\x0a\x09\x09ifNil: [\x0a\x09\x09\x09aClass instanceVariableNames]",
+messageSends: ["ifNotNil:ifNil:", "copyWithAll:", "instanceVariableNamesFor:", "superclass", "instanceVariableNames"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isIdentifier:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(aString)._match_("^[a-z_]\x5cw+$"._asRegexp());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isIdentifier:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "isIdentifier: aString\x0a\x09^ aString match: '^[a-z_]\x5cw+$' asRegexp",
+messageSends: ["match:", "asRegexp"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isVariableDefined:",
+category: 'private',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._instanceVariableNamesFor_(_st(self["@session"])._class()))._includes_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isVariableDefined:",{aString:aString},smalltalk.Repl)})},
+args: ["aString"],
+source: "isVariableDefined: aString\x0a\x09^ (self instanceVariableNamesFor: session class) includes: aString",
+messageSends: ["includes:", "instanceVariableNamesFor:", "class"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "nextResultName",
+category: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self["@resultCount"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@resultCount"]=(1);
+} else {
+self["@resultCount"]=_st(self["@resultCount"]).__plus((1));
+};
+$2="res".__comma(_st(self["@resultCount"])._asString());
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"nextResultName",{},smalltalk.Repl)})},
+args: [],
+source: "nextResultName\x0a\x09resultCount := resultCount\x0a    \x09ifNotNil: [resultCount + 1]\x0a    \x09ifNil: [1].\x0a    ^ 'res', resultCount asString",
+messageSends: ["ifNotNil:ifNil:", "+", ",", "asString"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onKeyPress:",
+category: 'private',
+fn: function (key){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(key)._ctrl())._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(key)._name()).__eq("l");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
+self._clearScreen();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"onKeyPress:",{key:key},smalltalk.Repl)})},
+args: ["key"],
+source: "onKeyPress: key\x0a\x09(key ctrl and: [key name = 'l'])\x0a\x09\x09ifTrue: [self clearScreen]",
+messageSends: ["ifTrue:", "clearScreen", "and:", "=", "name", "ctrl"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "parseAssignment:do:",
+category: 'private',
+fn: function (aString,aBlock){
+var self=this;
+var assignment;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+assignment=_st(_st(aString)._tokenize_(":="))._collect_((function(s){
+return smalltalk.withContext(function($ctx2) {
+return _st(s)._trimBoth();
+}, function($ctx2) {$ctx2.fillBlock({s:s},$ctx1)})}));
+$2=_st(_st(_st(assignment)._size()).__eq((2)))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._isIdentifier_(_st(assignment)._first());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value_value_(_st(assignment)._first(),_st(assignment)._last());
+} else {
+$1=_st(aBlock)._value_value_(nil,nil);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"parseAssignment:do:",{aString:aString,aBlock:aBlock,assignment:assignment},smalltalk.Repl)})},
+args: ["aString", "aBlock"],
+source: "parseAssignment: aString do: aBlock\x0a\x09\x22Assigns a new variable if the given string is an assignment expression. Calls the given block with name and value.\x0a\x09 If the string is not one no variable will be assigned and the block will be called with nil for both arguments.\x22\x0a\x09| assignment |\x0a\x09assignment := (aString tokenize: ':=') collect: [:s | s trimBoth].\x0a\x09^ (assignment size = 2 and: [self isIdentifier: assignment first])\x0a\x09\x09ifTrue: [aBlock value: assignment first value: assignment last]\x0a\x09\x09ifFalse: [aBlock value: nil value: nil]",
+messageSends: ["collect:", "trimBoth", "tokenize:", "ifTrue:ifFalse:", "value:value:", "first", "last", "and:", "isIdentifier:", "=", "size"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "presentResultNamed:withValue:",
+category: 'private',
+fn: function (varName,value){
+var self=this;
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=$Transcript();
+_st($1)._show_(_st(_st(_st(_st(varName).__comma(": ")).__comma(_st(_st(value)._class())._name())).__comma(" = ")).__comma(_st(value)._asString()));
+$2=_st($1)._cr();
+_st(self["@interface"])._prompt();
+return self}, function($ctx1) {$ctx1.fill(self,"presentResultNamed:withValue:",{varName:varName,value:value},smalltalk.Repl)})},
+args: ["varName", "value"],
+source: "presentResultNamed: varName withValue: value\x0a\x09Transcript show: varName, ': ', value class name, ' = ', value asString; cr.\x0a\x09interface prompt",
+messageSends: ["show:", ",", "asString", "name", "class", "cr", "prompt"],
+referencedClasses: ["Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "printWelcome",
+category: 'private',
+fn: function (){
+var self=this;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+_st($Transcript())._show_(_st(_st(_st("Welcome to Amber version ".__comma(_st(_st($Smalltalk())._current())._version())).__comma(" (NodeJS ")).__comma(_st(_st(process)._versions())._node())).__comma(")."));
+$1=$Transcript();
+_st($1)._show_("Type :q to exit.");
+$2=_st($1)._cr();
+return self}, function($ctx1) {$ctx1.fill(self,"printWelcome",{},smalltalk.Repl)})},
+args: [],
+source: "printWelcome\x0a\x09Transcript show: 'Welcome to Amber version ', Smalltalk current version, ' (NodeJS ', process versions node, ').'.\x0a\x09Transcript show: 'Type :q to exit.'; cr.",
+messageSends: ["show:", ",", "node", "versions", "version", "current", "cr"],
+referencedClasses: ["Smalltalk", "Transcript"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "processLine:",
+category: 'private',
+fn: function (buffer){
+var self=this;
+var show;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+show=(function(varName,value){
+return smalltalk.withContext(function($ctx2) {
+return self._presentResultNamed_withValue_(varName,value);
+}, function($ctx2) {$ctx2.fillBlock({varName:varName,value:value},$ctx1)})});
+$1=self._executeCommand_(buffer);
+if(! smalltalk.assert($1)){
+$2=self._isVariableDefined_(buffer);
+if(smalltalk.assert($2)){
+_st(show)._value_value_(buffer,_st(self["@session"])._perform_(buffer));
+} else {
+self._assignNewVariable_do_(buffer,show);
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"processLine:",{buffer:buffer,show:show},smalltalk.Repl)})},
+args: ["buffer"],
+source: "processLine: buffer\x0a\x09\x22Processes lines entered through the readline interface.\x22\x0a\x09| show |\x0a\x09show := [:varName :value | self presentResultNamed: varName withValue: value].\x0a\x09(self executeCommand: buffer) ifFalse: [\x0a\x09\x09(self isVariableDefined: buffer)\x0a\x09\x09\x09ifTrue: [show value: buffer value: (session perform: buffer)]\x0a\x09\x09\x09ifFalse: [self assignNewVariable: buffer do: show]]",
+messageSends: ["presentResultNamed:withValue:", "ifFalse:", "ifTrue:ifFalse:", "value:value:", "perform:", "assignNewVariable:do:", "isVariableDefined:", "executeCommand:"],
 referencedClasses: []
 }),
 smalltalk.Repl);
@@ -35687,6 +36134,25 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setPreviousVariablesFor:from:",
+category: 'private',
+fn: function (newObject,oldObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._instanceVariableNamesFor_(_st(oldObject)._class()))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newObject)._perform_withArguments_(_st(each).__comma(":"),[_st(oldObject)._perform_(each)]);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setPreviousVariablesFor:from:",{newObject:newObject,oldObject:oldObject},smalltalk.Repl)})},
+args: ["newObject", "oldObject"],
+source: "setPreviousVariablesFor: newObject from: oldObject\x0a\x09(self instanceVariableNamesFor: oldObject class) do: [:each |\x0a\x09\x09newObject perform: each, ':' withArguments: {oldObject perform: each}].",
+messageSends: ["do:", "perform:withArguments:", ",", "perform:", "instanceVariableNamesFor:", "class"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setPrompt",
@@ -35703,6 +36169,99 @@ referencedClasses: []
 }),
 smalltalk.Repl);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupCommands",
+category: 'initialization',
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+self["@commands"]=_st($Dictionary())._from_([_st([":q"]).__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(process)._exit();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})})),_st([""]).__minus_gt((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@interface"])._prompt();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]);
+return self}, function($ctx1) {$ctx1.fill(self,"setupCommands",{},smalltalk.Repl)})},
+args: [],
+source: "setupCommands\x0a\x09commands := Dictionary from: {\x0a\x09\x09{':q'} -> [process exit].\x0a\x09\x09{''} -> [interface prompt]}",
+messageSends: ["from:", "->", "exit", "prompt"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupHotkeys",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(_st(process)._stdin())._on_do_("keypress",(function(s,key){
+return smalltalk.withContext(function($ctx2) {
+$1=key;
+if(($receiver = $1) == nil || $receiver == undefined){
+return $1;
+} else {
+return self._onKeyPress_(key);
+};
+}, function($ctx2) {$ctx2.fillBlock({s:s,key:key},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setupHotkeys",{},smalltalk.Repl)})},
+args: [],
+source: "setupHotkeys\x0a\x09process stdin on: 'keypress' do: [:s :key | key ifNotNil: [self onKeyPress: key]].",
+messageSends: ["on:do:", "ifNotNil:", "onKeyPress:", "stdin"],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclass:withVariable:",
+category: 'private',
+fn: function (aClass,varName){
+var self=this;
+function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st($ClassBuilder())._new())._addSubclassOf_named_instanceVariableNames_package_(aClass,_st(self._subclassNameFor_(aClass))._asSymbol(),[varName],"Compiler-Core");
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclass:withVariable:",{aClass:aClass,varName:varName},smalltalk.Repl)})},
+args: ["aClass", "varName"],
+source: "subclass: aClass withVariable: varName\x0a\x09\x22Create subclass with new variable.\x22\x0a\x09^ ClassBuilder new\x0a\x09\x09addSubclassOf: aClass\x0a\x09\x09named: (self subclassNameFor: aClass) asSymbol\x0a\x09\x09instanceVariableNames: {varName}\x0a\x09\x09package: 'Compiler-Core'",
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "asSymbol", "subclassNameFor:", "new"],
+referencedClasses: ["ClassBuilder"]
+}),
+smalltalk.Repl);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "subclassNameFor:",
+category: 'private',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(_st(aClass)._name())._matchesOf_("\x5cd+$");
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=_st(_st(aClass)._name()).__comma("2");
+} else {
+var counter;
+counter=_st(_st(_st(_st(_st(aClass)._name())._matchesOf_("\x5cd+$"))._first())._asNumber()).__plus((1));
+counter;
+$1=_st(_st(aClass)._name())._replaceRegexp_with_("\x5cd+$"._asRegexp(),_st(counter)._asString());
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"subclassNameFor:",{aClass:aClass},smalltalk.Repl)})},
+args: ["aClass"],
+source: "subclassNameFor: aClass\x0a\x09^ (aClass name matchesOf: '\x5cd+$')\x0a\x09\x09ifNotNil: [ | counter |\x0a\x09\x09\x09counter := (aClass name matchesOf: '\x5cd+$') first asNumber + 1.\x0a\x09\x09\x09aClass name replaceRegexp: '\x5cd+$' asRegexp with: counter asString]\x0a\x09\x09ifNil: [\x0a\x09\x09\x09aClass name, '2'].",
+messageSends: ["ifNotNil:ifNil:", "+", "asNumber", "first", "matchesOf:", "name", "replaceRegexp:with:", "asRegexp", "asString", ","],
+referencedClasses: []
+}),
+smalltalk.Repl);
+
 
 smalltalk.addMethod(
 smalltalk.method({

+ 155 - 8
cli/st/AmberCli.st

@@ -892,7 +892,7 @@ main
 ! !
 
 Object subclass: #Repl
-	instanceVariableNames: 'readline interface util'
+	instanceVariableNames: 'readline interface util session resultCount commands'
 	package: 'AmberCli'!
 !Repl commentStamp!
 I am a class representing a REPL (Read Evaluate Print Loop) and provide a command line interface to Amber Smalltalk.
@@ -905,6 +905,10 @@ My runtime requirement is a functional Node.js executable with working Readline
 
 prompt
 	^'amber >> '
+!
+
+commands
+	^ commands
 ! !
 
 !Repl methodsFor: 'actions'!
@@ -914,25 +918,27 @@ close
 !
 
 createInterface
-	"No completion for now"
 	interface := readline createInterface: process stdin stdout: process stdout.
-	interface on: 'line' do: [:buffer  | self eval: buffer].
+	interface on: 'line' do: [:buffer | self processLine: buffer].
 	interface on: 'close' do: [self close].
-	self setPrompt.
+	self printWelcome; setupHotkeys; setPrompt.
 	interface prompt
 !
 
 eval: buffer
+	^ self eval: buffer on: DoIt new.
+!
+
+eval: buffer on: anObject
 	| result |
 	buffer isEmpty ifFalse: [
 		self try: [
-			result := Compiler new evaluateExpression: buffer.
-			Transcript show: result]
+			result := Compiler new evaluateExpression: buffer on: anObject]
 		catch: [:e |
 			e isSmalltalkError
 			    ifTrue: [ErrorHandler new handleError: e]
 			    ifFalse: [process stdout write: e jsStack]]].
-	interface prompt
+	^ result
 !
 
 setPrompt
@@ -943,8 +949,149 @@ setPrompt
 
 initialize
 	super initialize.
+	session := DoIt new.
 	readline := require value: 'readline'.
-	util := require value: 'util'
+	util := require value: 'util'.
+	self setupCommands
+!
+
+setupHotkeys
+	process stdin on: 'keypress' do: [:s :key | key ifNotNil: [self onKeyPress: key]].
+!
+
+setupCommands
+	commands := Dictionary from: {
+		{':q'} -> [process exit].
+		{''} -> [interface prompt]}
+! !
+
+!Repl methodsFor: 'private'!
+
+addVariableNamed: aString to: anObject
+	| newClass newObject |
+	newClass := self subclass: anObject class withVariable: aString.
+	self encapsulateVariable: aString withValue: anObject in: newClass.
+	newObject := newClass new.
+	self setPreviousVariablesFor: newObject from: anObject.
+	^ newObject
+!
+
+assignNewVariable: buffer do: aBlock
+	"Assigns a new variable and calls the given block with the variable's name and value
+	 if buffer contains an assignment expression. If it doesn't the block is called with nil for
+	 both arguments."
+	^ self parseAssignment: buffer do: [ :name :expr || varName value |
+		varName := name ifNil: [self nextResultName].
+		session := self addVariableNamed: varName to: session.
+		value := self eval: varName, ' := ', (expr ifNil: [buffer]) on: session.
+		aBlock value: varName value: value]
+!
+
+encapsulateVariable: aString withValue: anObject in: aClass
+	"Add getter and setter for given variable to session."
+	| compiler |
+	compiler := Compiler new.
+	compiler install: aString, ': anObject ^ ', aString, ' := anObject' forClass: aClass category: 'session'.
+	compiler install: aString, ' ^ ', aString forClass: aClass category: 'session'.
+!
+
+executeCommand: aString
+	"Tries to process the given string as a command. Returns true if it was a command, false if not."
+	self commands keysAndValuesDo: [:names :cmd |
+		(names includes: aString) ifTrue: [
+			cmd value.
+			^ true]].
+	^ false
+!
+
+instanceVariableNamesFor: aClass
+	"Yields all instance variable names for the given class, including inherited ones."
+	^ aClass superclass
+		ifNotNil: [
+			aClass instanceVariableNames copyWithAll: (self instanceVariableNamesFor: aClass superclass)]
+		ifNil: [
+			aClass instanceVariableNames]
+!
+
+isIdentifier: aString
+	^ aString match: '^[a-z_]\w+$' asRegexp
+!
+
+isVariableDefined: aString
+	^ (self instanceVariableNamesFor: session class) includes: aString
+!
+
+nextResultName
+	resultCount := resultCount
+    	ifNotNil: [resultCount + 1]
+    	ifNil: [1].
+    ^ 'res', resultCount asString
+!
+
+onKeyPress: key
+	(key ctrl and: [key name = 'l'])
+		ifTrue: [self clearScreen]
+!
+
+clearScreen
+	| esc cls |
+	esc := String fromCharCode: 27.
+	cls := esc, '[2J', esc, '[0;0f'.
+	process stdout write: cls.
+	interface prompt
+!
+
+parseAssignment: aString do: aBlock
+	"Assigns a new variable if the given string is an assignment expression. Calls the given block with name and value.
+	 If the string is not one no variable will be assigned and the block will be called with nil for both arguments."
+	| assignment |
+	assignment := (aString tokenize: ':=') collect: [:s | s trimBoth].
+	^ (assignment size = 2 and: [self isIdentifier: assignment first])
+		ifTrue: [aBlock value: assignment first value: assignment last]
+		ifFalse: [aBlock value: nil value: nil]
+!
+
+presentResultNamed: varName withValue: value
+	Transcript show: varName, ': ', value class name, ' = ', value asString; cr.
+	interface prompt
+!
+
+printWelcome
+	Transcript show: 'Welcome to Amber version ', Smalltalk current version, ' (NodeJS ', process versions node, ').'.
+	Transcript show: 'Type :q to exit.'; cr.
+!
+
+processLine: buffer
+	"Processes lines entered through the readline interface."
+	| show |
+	show := [:varName :value | self presentResultNamed: varName withValue: value].
+	(self executeCommand: buffer) ifFalse: [
+		(self isVariableDefined: buffer)
+			ifTrue: [show value: buffer value: (session perform: buffer)]
+			ifFalse: [self assignNewVariable: buffer do: show]]
+!
+
+setPreviousVariablesFor: newObject from: oldObject
+	(self instanceVariableNamesFor: oldObject class) do: [:each |
+		newObject perform: each, ':' withArguments: {oldObject perform: each}].
+!
+
+subclass: aClass withVariable: varName
+	"Create subclass with new variable."
+	^ ClassBuilder new
+		addSubclassOf: aClass
+		named: (self subclassNameFor: aClass) asSymbol
+		instanceVariableNames: {varName}
+		package: 'Compiler-Core'
+!
+
+subclassNameFor: aClass
+	^ (aClass name matchesOf: '\d+$')
+		ifNotNil: [ | counter |
+			counter := (aClass name matchesOf: '\d+$') first asNumber + 1.
+			aClass name replaceRegexp: '\d+$' asRegexp with: counter asString]
+		ifNil: [
+			aClass name, '2'].
 ! !
 
 !Repl class methodsFor: 'initialization'!

+ 6 - 2
grunt/tasks/grunt-amberc.js

@@ -15,14 +15,15 @@ module.exports = function(grunt) {
        helloWorld: {
          src: ['projects/HelloWorld/st/HelloWorld.st'], // REQUIRED
          output_dir: 'projects/HelloWorld/js',  // optional
+         libraries: 'Canvas',                   // optional
+         jsGlobals: ['global1', 'global2'],     // optional
          main_class: 'HelloWorld',              // optional
          output_name: 'helloWorld',            // optional
-         libraries: 'Canvas',                  // optional
          init: 'myInit',                       // optional
          main_file: 'myMain.js',               // optional
          deploy: true,                         // optional
          output_suffix: 'mySuffix',            // optional
-         library_suffix: '-0.9'               // optional
+         library_suffix: '-0.9'                // optional
        },
      },
 
@@ -112,6 +113,9 @@ module.exports = function(grunt) {
     if (undefined !== data.output_dir) {
       configuration.output_dir = data.output_dir;
     }
+    if (undefined !== data.jsGlobals) {
+      configuration.jsGlobals.push.apply(configuration.jsGlobals, data.jsGlobals);
+    }
     configuration.verbose = data.verbose;
     return configuration;
   }

+ 4 - 4
js/Canvas.deploy.js

@@ -741,7 +741,7 @@ var self=this;
 function $TagBrush(){return smalltalk.TagBrush||(typeof TagBrush=="undefined"?nil:TagBrush)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HTMLCanvas.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self["@root"];
 if(($receiver = $1) == nil || $receiver == undefined){
 self["@root"]=_st($TagBrush())._fromString_canvas_("div",self);
@@ -1727,7 +1727,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=self["@current"];
 if(($receiver = $1) == nil || $receiver == undefined){
-$2=smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []);
+$2=smalltalk.HTMLSnippet.klass.superclass.fn.prototype._new.apply(_st(self), []);
 _st($2)._initializeFromJQuery_(_st(document)._asJQuery());
 $3=_st($2)._yourself();
 self["@current"]=$3;
@@ -1746,7 +1746,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HTMLSnippet.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self._isDOMAvailable();
 if(smalltalk.assert($1)){
 self._ensureCurrent();
@@ -2584,7 +2584,7 @@ $1=_st($HTMLCanvas())._isMSIE();
 if(smalltalk.assert($1)){
 _st(_st(self._element())._styleSheet())._cssText_(aString);
 } else {
-smalltalk.TagBrush.fn.prototype._with_.apply(_st(self), [aString]);
+smalltalk.StyleTag.superclass.fn.prototype._with_.apply(_st(self), [aString]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"with:",{aString:aString},smalltalk.StyleTag)})},
 messageSends: ["ifTrue:ifFalse:", "isMSIE", "cssText:", "styleSheet", "element", "with:"]}),

+ 4 - 4
js/Canvas.js

@@ -1023,7 +1023,7 @@ var self=this;
 function $TagBrush(){return smalltalk.TagBrush||(typeof TagBrush=="undefined"?nil:TagBrush)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HTMLCanvas.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self["@root"];
 if(($receiver = $1) == nil || $receiver == undefined){
 self["@root"]=_st($TagBrush())._fromString_canvas_("div",self);
@@ -2370,7 +2370,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=self["@current"];
 if(($receiver = $1) == nil || $receiver == undefined){
-$2=smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []);
+$2=smalltalk.HTMLSnippet.klass.superclass.fn.prototype._new.apply(_st(self), []);
 _st($2)._initializeFromJQuery_(_st(document)._asJQuery());
 $3=_st($2)._yourself();
 self["@current"]=$3;
@@ -2394,7 +2394,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HTMLSnippet.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self._isDOMAvailable();
 if(smalltalk.assert($1)){
 self._ensureCurrent();
@@ -3594,7 +3594,7 @@ $1=_st($HTMLCanvas())._isMSIE();
 if(smalltalk.assert($1)){
 _st(_st(self._element())._styleSheet())._cssText_(aString);
 } else {
-smalltalk.TagBrush.fn.prototype._with_.apply(_st(self), [aString]);
+smalltalk.StyleTag.superclass.fn.prototype._with_.apply(_st(self), [aString]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"with:",{aString:aString},smalltalk.StyleTag)})},
 args: ["aString"],

+ 1 - 1
js/Compiler-AST.deploy.js

@@ -310,7 +310,7 @@ selector: "postCopy",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._postCopy.apply(_st(self), []);
+smalltalk.Node.superclass.fn.prototype._postCopy.apply(_st(self), []);
 _st(self._nodes())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._parent_(self);

+ 1 - 1
js/Compiler-AST.js

@@ -422,7 +422,7 @@ category: 'copying',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._postCopy.apply(_st(self), []);
+smalltalk.Node.superclass.fn.prototype._postCopy.apply(_st(self), []);
 _st(self._nodes())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._parent_(self);

+ 2 - 1
js/Compiler-Core.deploy.js

@@ -134,12 +134,13 @@ var $2,$3,$1;
 _st(self._semanticAnalyzer())._visit_(aNode);
 ir=_st(self._translator())._visit_(aNode);
 $2=self._irTranslator();
+_st($2)._currentClass_(self._currentClass());
 _st($2)._visit_(ir);
 $3=_st($2)._contents();
 $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},smalltalk.CodeGenerator)})},
-messageSends: ["visit:", "semanticAnalyzer", "translator", "irTranslator", "contents"]}),
+messageSends: ["visit:", "semanticAnalyzer", "translator", "currentClass:", "irTranslator", "currentClass", "contents"]}),
 smalltalk.CodeGenerator);
 
 smalltalk.addMethod(

+ 3 - 2
js/Compiler-Core.js

@@ -177,14 +177,15 @@ var $2,$3,$1;
 _st(self._semanticAnalyzer())._visit_(aNode);
 ir=_st(self._translator())._visit_(aNode);
 $2=self._irTranslator();
+_st($2)._currentClass_(self._currentClass());
 _st($2)._visit_(ir);
 $3=_st($2)._contents();
 $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},smalltalk.CodeGenerator)})},
 args: ["aNode"],
-source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09^ self irTranslator\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
-messageSends: ["visit:", "semanticAnalyzer", "translator", "irTranslator", "contents"],
+source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09^ self irTranslator\x0a\x09\x09currentClass: self currentClass;\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
+messageSends: ["visit:", "semanticAnalyzer", "translator", "currentClass:", "irTranslator", "currentClass", "contents"],
 referencedClasses: []
 }),
 smalltalk.CodeGenerator);

+ 1 - 1
js/Compiler-Exceptions.deploy.js

@@ -149,7 +149,7 @@ selector: "handleError:",
 fn: function (anError){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.ErrorHandler.fn.prototype._handleError_.apply(_st(self), [anError]);
+smalltalk.RethrowErrorHandler.superclass.fn.prototype._handleError_.apply(_st(self), [anError]);
 self._basicSignal_(anError);
 return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},smalltalk.RethrowErrorHandler)})},
 messageSends: ["handleError:", "basicSignal:"]}),

+ 1 - 1
js/Compiler-Exceptions.js

@@ -208,7 +208,7 @@ category: 'error handling',
 fn: function (anError){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.ErrorHandler.fn.prototype._handleError_.apply(_st(self), [anError]);
+smalltalk.RethrowErrorHandler.superclass.fn.prototype._handleError_.apply(_st(self), [anError]);
 self._basicSignal_(anError);
 return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},smalltalk.RethrowErrorHandler)})},
 args: ["anError"],

+ 36 - 11
js/Compiler-IR.deploy.js

@@ -942,7 +942,7 @@ selector: "scope:",
 fn: function (aScope){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IRScopedInstruction.fn.prototype._scope_.apply(_st(self), [aScope]);
+smalltalk.IRClosureInstruction.superclass.fn.prototype._scope_.apply(_st(self), [aScope]);
 _st(aScope)._instruction_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"scope:",{aScope:aScope},smalltalk.IRClosureInstruction)})},
 messageSends: ["scope:", "instruction:"]}),
@@ -1952,7 +1952,7 @@ smalltalk.IRVisitor);
 
 
 
-smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream'], 'Compiler-IR');
+smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream', 'currentClass'], 'Compiler-IR');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "contents",
@@ -1966,6 +1966,30 @@ return $1;
 messageSends: ["contents", "stream"]}),
 smalltalk.IRJSTranslator);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "currentClass",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@currentClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"currentClass",{},smalltalk.IRJSTranslator)})},
+messageSends: []}),
+smalltalk.IRJSTranslator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "currentClass:",
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@currentClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"currentClass:",{aClass:aClass},smalltalk.IRJSTranslator)})},
+messageSends: []}),
+smalltalk.IRJSTranslator);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
@@ -1973,7 +1997,7 @@ fn: function (){
 var self=this;
 function $JSStream(){return smalltalk.JSStream||(typeof JSStream=="undefined"?nil:JSStream)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IRVisitor.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.IRJSTranslator.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@stream"]=_st($JSStream())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.IRJSTranslator)})},
 messageSends: ["initialize", "new"]}),
@@ -2030,7 +2054,7 @@ return _st(_st(each)._name())._asVariableName();
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)})})));
 return _st(self._stream())._nextPutBlockContextFor_during_(anIRClosure,(function(){
 return smalltalk.withContext(function($ctx3) {
-return smalltalk.IRVisitor.fn.prototype._visitIRClosure_.apply(_st(self), [anIRClosure]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRClosure_.apply(_st(self), [anIRClosure]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,3)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),_st(anIRClosure)._arguments());
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRClosure:",{anIRClosure:anIRClosure},smalltalk.IRJSTranslator)})},
@@ -2107,10 +2131,10 @@ $2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
 if(smalltalk.assert($2)){
 return _st(self._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) {
-return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 }, function($ctx5) {$ctx5.fillBlock({},$ctx4,9)})}));
 } else {
-return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
 }, function($ctx4) {$ctx4.fillBlock({},$ctx3,5)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}),_st(anIRMethod)._arguments());
@@ -2127,7 +2151,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._stream())._nextPutNonLocalReturnWith_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.IRVisitor.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRNonLocalReturn:",{anIRNonLocalReturn:anIRNonLocalReturn},smalltalk.IRJSTranslator)})},
 messageSends: ["nextPutNonLocalReturnWith:", "stream", "visitIRNonLocalReturn:"]}),
@@ -2141,7 +2165,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._stream())._nextPutReturnWith_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.IRVisitor.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRReturn:",{anIRReturn:anIRReturn},smalltalk.IRJSTranslator)})},
 messageSends: ["nextPutReturnWith:", "stream", "visitIRReturn:"]}),
@@ -2280,7 +2304,8 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 $1=self._stream();
-_st($1)._nextPutAll_(_st(_st(_st(anIRSend)._classSend())._asJavascript()).__comma(".fn.prototype."));
+_st($1)._nextPutAll_(_st(self._currentClass())._asJavascript());
+_st($1)._nextPutAll_(".superclass.fn.prototype.");
 _st($1)._nextPutAll_(_st(_st(_st(anIRSend)._selector())._asSelector()).__comma(".apply("));
 $2=_st($1)._nextPutAll_("_st(");
 self._visit_(_st(_st(anIRSend)._instructions())._first());
@@ -2294,7 +2319,7 @@ return _st(self._stream())._nextPutAll_(",");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 _st(self._stream())._nextPutAll_("])");
 return self}, function($ctx1) {$ctx1.fill(self,"visitSuperSend:",{anIRSend:anIRSend},smalltalk.IRJSTranslator)})},
-messageSends: ["nextPutAll:", "stream", ",", "asJavascript", "classSend", "asSelector", "selector", "visit:", "first", "instructions", "do:separatedBy:", "allButFirst"]}),
+messageSends: ["nextPutAll:", "stream", "asJavascript", "currentClass", ",", "asSelector", "selector", "visit:", "first", "instructions", "do:separatedBy:", "allButFirst"]}),
 smalltalk.IRJSTranslator);
 
 
@@ -2319,7 +2344,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.JSStream.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@stream"]=""._writeStream();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.JSStream)})},
 messageSends: ["initialize", "writeStream"]}),

+ 47 - 12
js/Compiler-IR.js

@@ -1220,7 +1220,7 @@ category: 'accessing',
 fn: function (aScope){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IRScopedInstruction.fn.prototype._scope_.apply(_st(self), [aScope]);
+smalltalk.IRClosureInstruction.superclass.fn.prototype._scope_.apply(_st(self), [aScope]);
 _st(aScope)._instruction_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"scope:",{aScope:aScope},smalltalk.IRClosureInstruction)})},
 args: ["aScope"],
@@ -2626,7 +2626,7 @@ smalltalk.IRVisitor);
 
 
 
-smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream'], 'Compiler-IR');
+smalltalk.addClass('IRJSTranslator', smalltalk.IRVisitor, ['stream', 'currentClass'], 'Compiler-IR');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "contents",
@@ -2645,6 +2645,40 @@ referencedClasses: []
 }),
 smalltalk.IRJSTranslator);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "currentClass",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@currentClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"currentClass",{},smalltalk.IRJSTranslator)})},
+args: [],
+source: "currentClass\x0a\x09^ currentClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRJSTranslator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "currentClass:",
+category: 'accessing',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@currentClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"currentClass:",{aClass:aClass},smalltalk.IRJSTranslator)})},
+args: ["aClass"],
+source: "currentClass: aClass\x0a\x09currentClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRJSTranslator);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
@@ -2653,7 +2687,7 @@ fn: function (){
 var self=this;
 function $JSStream(){return smalltalk.JSStream||(typeof JSStream=="undefined"?nil:JSStream)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IRVisitor.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.IRJSTranslator.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@stream"]=_st($JSStream())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.IRJSTranslator)})},
 args: [],
@@ -2730,7 +2764,7 @@ return _st(_st(each)._name())._asVariableName();
 }, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)})})));
 return _st(self._stream())._nextPutBlockContextFor_during_(anIRClosure,(function(){
 return smalltalk.withContext(function($ctx3) {
-return smalltalk.IRVisitor.fn.prototype._visitIRClosure_.apply(_st(self), [anIRClosure]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRClosure_.apply(_st(self), [anIRClosure]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,3)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),_st(anIRClosure)._arguments());
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRClosure:",{anIRClosure:anIRClosure},smalltalk.IRJSTranslator)})},
@@ -2822,10 +2856,10 @@ $2=_st(_st(anIRMethod)._scope())._hasNonLocalReturn();
 if(smalltalk.assert($2)){
 return _st(self._stream())._nextPutNonLocalReturnHandlingWith_((function(){
 return smalltalk.withContext(function($ctx5) {
-return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 }, function($ctx5) {$ctx5.fillBlock({},$ctx4,9)})}));
 } else {
-return smalltalk.IRVisitor.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRMethod_.apply(_st(self), [anIRMethod]);
 };
 }, function($ctx4) {$ctx4.fillBlock({},$ctx3,5)})}));
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}),_st(anIRMethod)._arguments());
@@ -2847,7 +2881,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._stream())._nextPutNonLocalReturnWith_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.IRVisitor.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRNonLocalReturn:",{anIRNonLocalReturn:anIRNonLocalReturn},smalltalk.IRJSTranslator)})},
 args: ["anIRNonLocalReturn"],
@@ -2866,7 +2900,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._stream())._nextPutReturnWith_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.IRVisitor.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
+return smalltalk.IRJSTranslator.superclass.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRReturn:",{anIRReturn:anIRReturn},smalltalk.IRJSTranslator)})},
 args: ["anIRReturn"],
@@ -3050,7 +3084,8 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 $1=self._stream();
-_st($1)._nextPutAll_(_st(_st(_st(anIRSend)._classSend())._asJavascript()).__comma(".fn.prototype."));
+_st($1)._nextPutAll_(_st(self._currentClass())._asJavascript());
+_st($1)._nextPutAll_(".superclass.fn.prototype.");
 _st($1)._nextPutAll_(_st(_st(_st(anIRSend)._selector())._asSelector()).__comma(".apply("));
 $2=_st($1)._nextPutAll_("_st(");
 self._visit_(_st(_st(anIRSend)._instructions())._first());
@@ -3065,8 +3100,8 @@ return _st(self._stream())._nextPutAll_(",");
 _st(self._stream())._nextPutAll_("])");
 return self}, function($ctx1) {$ctx1.fill(self,"visitSuperSend:",{anIRSend:anIRSend},smalltalk.IRJSTranslator)})},
 args: ["anIRSend"],
-source: "visitSuperSend: anIRSend\x0a\x09self stream\x0a\x09\x09nextPutAll: anIRSend classSend asJavascript, '.fn.prototype.';\x0a\x09\x09nextPutAll: anIRSend selector asSelector, '.apply(';\x0a\x09\x09nextPutAll: '_st('.\x0a\x09self visit: anIRSend instructions first.\x0a\x09self stream nextPutAll: '), ['.\x0a\x09anIRSend instructions allButFirst\x0a\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
-messageSends: ["nextPutAll:", "stream", ",", "asJavascript", "classSend", "asSelector", "selector", "visit:", "first", "instructions", "do:separatedBy:", "allButFirst"],
+source: "visitSuperSend: anIRSend\x0a\x09self stream\x0a\x09\x09nextPutAll: self currentClass asJavascript;\x0a\x09\x09nextPutAll: '.superclass.fn.prototype.';\x0a\x09\x09nextPutAll: anIRSend selector asSelector, '.apply(';\x0a\x09\x09nextPutAll: '_st('.\x0a\x09self visit: anIRSend instructions first.\x0a\x09self stream nextPutAll: '), ['.\x0a\x09anIRSend instructions allButFirst\x0a\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
+messageSends: ["nextPutAll:", "stream", "asJavascript", "currentClass", ",", "asSelector", "selector", "visit:", "first", "instructions", "do:separatedBy:", "allButFirst"],
 referencedClasses: []
 }),
 smalltalk.IRJSTranslator);
@@ -3099,7 +3134,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.JSStream.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@stream"]=""._writeStream();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.JSStream)})},
 args: [],

+ 8 - 7
js/Compiler-Inlining.deploy.js

@@ -316,7 +316,7 @@ _st(anIRNonLocalReturn)._replaceWith_(localReturn);
 $4=localReturn;
 return $4;
 };
-$5=smalltalk.IRVisitor.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
+$5=smalltalk.IRInliner.superclass.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
 return $5;
 }, function($ctx1) {$ctx1.fill(self,"transformNonLocalReturn:",{anIRNonLocalReturn:anIRNonLocalReturn,localReturn:localReturn},smalltalk.IRInliner)})},
 messageSends: ["ifTrue:", "canInlineNonLocalReturns", "scope", "removeNonLocalReturn:", "methodScope", "scope:", "new", "yourself", "do:", "instructions", "add:", "replaceWith:", "visitIRNonLocalReturn:"]}),
@@ -333,7 +333,7 @@ $2=self._shouldInlineAssignment_(anIRAssignment);
 if(smalltalk.assert($2)){
 $1=_st(self._assignmentInliner())._inlineAssignment_(anIRAssignment);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRAssignment_.apply(_st(self), [anIRAssignment]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRAssignment_.apply(_st(self), [anIRAssignment]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRAssignment:",{anIRAssignment:anIRAssignment},smalltalk.IRInliner)})},
@@ -364,7 +364,7 @@ $2=self._shouldInlineReturn_(anIRReturn);
 if(smalltalk.assert($2)){
 $1=_st(self._returnInliner())._inlineReturn_(anIRReturn);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRReturn:",{anIRReturn:anIRReturn},smalltalk.IRInliner)})},
@@ -382,7 +382,7 @@ $2=self._shouldInlineSend_(anIRSend);
 if(smalltalk.assert($2)){
 $1=_st(self._sendInliner())._inlineSend_(anIRSend);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRSend_.apply(_st(self), [anIRSend]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRSend_.apply(_st(self), [anIRSend]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRSend:",{anIRSend:anIRSend},smalltalk.IRInliner)})},
@@ -1019,7 +1019,7 @@ var inlinedClosure,statements;
 function $IRAssignment(){return smalltalk.IRAssignment||(typeof IRAssignment=="undefined"?nil:IRAssignment)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4;
-inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
+inlinedClosure=smalltalk.IRAssignmentInliner.superclass.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
 _st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -1050,7 +1050,7 @@ var closure,statements;
 function $IRReturn(){return smalltalk.IRReturn||(typeof IRReturn=="undefined"?nil:IRReturn)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4;
-closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
+closure=smalltalk.IRReturnInliner.superclass.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
 _st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -1118,12 +1118,13 @@ _st(self._semanticAnalyzer())._visit_(aNode);
 ir=_st(self._translator())._visit_(aNode);
 _st(self._inliner())._visit_(ir);
 $2=self._irTranslator();
+_st($2)._currentClass_(self._currentClass());
 _st($2)._visit_(ir);
 $3=_st($2)._contents();
 $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},smalltalk.InliningCodeGenerator)})},
-messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "irTranslator", "contents"]}),
+messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "currentClass:", "irTranslator", "currentClass", "contents"]}),
 smalltalk.InliningCodeGenerator);
 
 smalltalk.addMethod(

+ 9 - 8
js/Compiler-Inlining.js

@@ -427,7 +427,7 @@ _st(anIRNonLocalReturn)._replaceWith_(localReturn);
 $4=localReturn;
 return $4;
 };
-$5=smalltalk.IRVisitor.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
+$5=smalltalk.IRInliner.superclass.fn.prototype._visitIRNonLocalReturn_.apply(_st(self), [anIRNonLocalReturn]);
 return $5;
 }, function($ctx1) {$ctx1.fill(self,"transformNonLocalReturn:",{anIRNonLocalReturn:anIRNonLocalReturn,localReturn:localReturn},smalltalk.IRInliner)})},
 args: ["anIRNonLocalReturn"],
@@ -449,7 +449,7 @@ $2=self._shouldInlineAssignment_(anIRAssignment);
 if(smalltalk.assert($2)){
 $1=_st(self._assignmentInliner())._inlineAssignment_(anIRAssignment);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRAssignment_.apply(_st(self), [anIRAssignment]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRAssignment_.apply(_st(self), [anIRAssignment]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRAssignment:",{anIRAssignment:anIRAssignment},smalltalk.IRInliner)})},
@@ -490,7 +490,7 @@ $2=self._shouldInlineReturn_(anIRReturn);
 if(smalltalk.assert($2)){
 $1=_st(self._returnInliner())._inlineReturn_(anIRReturn);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRReturn_.apply(_st(self), [anIRReturn]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRReturn:",{anIRReturn:anIRReturn},smalltalk.IRInliner)})},
@@ -513,7 +513,7 @@ $2=self._shouldInlineSend_(anIRSend);
 if(smalltalk.assert($2)){
 $1=_st(self._sendInliner())._inlineSend_(anIRSend);
 } else {
-$1=smalltalk.IRVisitor.fn.prototype._visitIRSend_.apply(_st(self), [anIRSend]);
+$1=smalltalk.IRInliner.superclass.fn.prototype._visitIRSend_.apply(_st(self), [anIRSend]);
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"visitIRSend:",{anIRSend:anIRSend},smalltalk.IRInliner)})},
@@ -1328,7 +1328,7 @@ var inlinedClosure,statements;
 function $IRAssignment(){return smalltalk.IRAssignment||(typeof IRAssignment=="undefined"?nil:IRAssignment)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4;
-inlinedClosure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
+inlinedClosure=smalltalk.IRAssignmentInliner.superclass.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(inlinedClosure)._instructions())._last())._instructions();
 _st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -1365,7 +1365,7 @@ var closure,statements;
 function $IRReturn(){return smalltalk.IRReturn||(typeof IRReturn=="undefined"?nil:IRReturn)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4;
-closure=smalltalk.IRSendInliner.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
+closure=smalltalk.IRReturnInliner.superclass.fn.prototype._inlineClosure_.apply(_st(self), [anIRClosure]);
 statements=_st(_st(_st(closure)._instructions())._last())._instructions();
 _st(statements)._ifNotEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -1449,14 +1449,15 @@ _st(self._semanticAnalyzer())._visit_(aNode);
 ir=_st(self._translator())._visit_(aNode);
 _st(self._inliner())._visit_(ir);
 $2=self._irTranslator();
+_st($2)._currentClass_(self._currentClass());
 _st($2)._visit_(ir);
 $3=_st($2)._contents();
 $1=$3;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},smalltalk.InliningCodeGenerator)})},
 args: ["aNode"],
-source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09self inliner visit: ir.\x0a\x0a\x09^ self irTranslator\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
-messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "irTranslator", "contents"],
+source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09self inliner visit: ir.\x0a\x0a\x09^ self irTranslator\x0a\x09\x09currentClass: self currentClass;\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
+messageSends: ["visit:", "semanticAnalyzer", "translator", "inliner", "currentClass:", "irTranslator", "currentClass", "contents"],
 referencedClasses: []
 }),
 smalltalk.InliningCodeGenerator);

+ 15 - 15
js/Compiler-Interpreter.deploy.js

@@ -1023,7 +1023,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ASTInterpreter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@shouldReturn"]=false;
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ASTInterpreter)})},
 messageSends: ["initialize"]}),
@@ -1499,7 +1499,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.ASTInterpreter.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ASTSteppingInterpreter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@continuation"]=(function(){
 return smalltalk.withContext(function($ctx2) {
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})});
@@ -1516,7 +1516,7 @@ return smalltalk.withContext(function($ctx1) {
 self["@nextNode"]=aNode;
 self["@continuation"]=(function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.ASTInterpreter.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
+return smalltalk.ASTSteppingInterpreter.superclass.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})});
 return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTSteppingInterpreter)})},
 messageSends: ["interpret:continue:"]}),
@@ -1684,7 +1684,7 @@ var $1;
 $1=_st(self._blockIndex()).__gt_eq(_st(self._context())._index());
 if(! smalltalk.assert($1)){
 self._increaseBlockIndex();
-smalltalk.NodeVisitor.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
+smalltalk.ASTPCNodeVisitor.superclass.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},smalltalk.ASTPCNodeVisitor)})},
 messageSends: ["ifFalse:", ">=", "blockIndex", "index", "context", "increaseBlockIndex", "visitBlockNode:"]}),
@@ -1708,7 +1708,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-smalltalk.NodeVisitor.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
+smalltalk.ASTPCNodeVisitor.superclass.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
 $1=_st(self._pc()).__eq(_st(self._context())._pc());
 if(! smalltalk.assert($1)){
 $2=_st(aNode)._shouldBeInlined();
@@ -1928,14 +1928,14 @@ smalltalk.method({
 selector: "pop",
 fn: function (){
 var self=this;
-var value;
+var peekedValue;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-value=self._peek();
+peekedValue=self._peek();
 _st(self._stack())._removeLast();
-$1=value;
+$1=peekedValue;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"pop",{value:value},smalltalk.Interpreter)})},
+}, function($ctx1) {$ctx1.fill(self,"pop",{peekedValue:peekedValue},smalltalk.Interpreter)})},
 messageSends: ["peek", "removeLast", "stack"]}),
 smalltalk.Interpreter);
 
@@ -2142,7 +2142,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 $1=self._shouldReturn();
 if(! smalltalk.assert($1)){
-smalltalk.NodeVisitor.fn.prototype._visit_.apply(_st(self), [aNode]);
+smalltalk.Interpreter.superclass.fn.prototype._visit_.apply(_st(self), [aNode]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"visit:",{aNode:aNode},smalltalk.Interpreter)})},
 messageSends: ["ifFalse:", "shouldReturn", "visit:"]}),
@@ -2153,13 +2153,13 @@ smalltalk.method({
 selector: "visitAssignmentNode:",
 fn: function (aNode){
 var self=this;
-var value;
+var poppedValue;
 return smalltalk.withContext(function($ctx1) { 
-value=self._pop();
+poppedValue=self._pop();
 self._pop();
-self._push_(value);
-self._assign_to_(_st(aNode)._left(),value);
-return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode,value:value},smalltalk.Interpreter)})},
+self._push_(poppedValue);
+self._assign_to_(_st(aNode)._left(),poppedValue);
+return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode,poppedValue:poppedValue},smalltalk.Interpreter)})},
 messageSends: ["pop", "push:", "assign:to:", "left"]}),
 smalltalk.Interpreter);
 

+ 17 - 17
js/Compiler-Interpreter.js

@@ -1354,7 +1354,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ASTInterpreter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@shouldReturn"]=false;
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ASTInterpreter)})},
 args: [],
@@ -1971,7 +1971,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.ASTInterpreter.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ASTSteppingInterpreter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@continuation"]=(function(){
 return smalltalk.withContext(function($ctx2) {
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})});
@@ -1993,7 +1993,7 @@ return smalltalk.withContext(function($ctx1) {
 self["@nextNode"]=aNode;
 self["@continuation"]=(function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.ASTInterpreter.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
+return smalltalk.ASTSteppingInterpreter.superclass.fn.prototype._interpret_continue_.apply(_st(self), [aNode,aBlock]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})});
 return self}, function($ctx1) {$ctx1.fill(self,"interpret:continue:",{aNode:aNode,aBlock:aBlock},smalltalk.ASTSteppingInterpreter)})},
 args: ["aNode", "aBlock"],
@@ -2222,7 +2222,7 @@ var $1;
 $1=_st(self._blockIndex()).__gt_eq(_st(self._context())._index());
 if(! smalltalk.assert($1)){
 self._increaseBlockIndex();
-smalltalk.NodeVisitor.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
+smalltalk.ASTPCNodeVisitor.superclass.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},smalltalk.ASTPCNodeVisitor)})},
 args: ["aNode"],
@@ -2256,7 +2256,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-smalltalk.NodeVisitor.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
+smalltalk.ASTPCNodeVisitor.superclass.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
 $1=_st(self._pc()).__eq(_st(self._context())._pc());
 if(! smalltalk.assert($1)){
 $2=_st(aNode)._shouldBeInlined();
@@ -2546,16 +2546,16 @@ selector: "pop",
 category: 'stack',
 fn: function (){
 var self=this;
-var value;
+var peekedValue;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-value=self._peek();
+peekedValue=self._peek();
 _st(self._stack())._removeLast();
-$1=value;
+$1=peekedValue;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"pop",{value:value},smalltalk.Interpreter)})},
+}, function($ctx1) {$ctx1.fill(self,"pop",{peekedValue:peekedValue},smalltalk.Interpreter)})},
 args: [],
-source: "pop\x0a\x09\x22Pop an object from the context stack\x22\x0a\x09\x0a\x09| value |\x0a\x09\x0a\x09value := self peek.\x0a\x09self stack removeLast.\x0a\x09^ value",
+source: "pop\x0a\x09\x22Pop an object from the context stack\x22\x0a\x09\x0a\x09| peekedValue |\x0a\x09\x0a\x09peekedValue := self peek.\x0a\x09self stack removeLast.\x0a\x09^ peekedValue",
 messageSends: ["peek", "removeLast", "stack"],
 referencedClasses: []
 }),
@@ -2825,7 +2825,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 $1=self._shouldReturn();
 if(! smalltalk.assert($1)){
-smalltalk.NodeVisitor.fn.prototype._visit_.apply(_st(self), [aNode]);
+smalltalk.Interpreter.superclass.fn.prototype._visit_.apply(_st(self), [aNode]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"visit:",{aNode:aNode},smalltalk.Interpreter)})},
 args: ["aNode"],
@@ -2841,15 +2841,15 @@ selector: "visitAssignmentNode:",
 category: 'visiting',
 fn: function (aNode){
 var self=this;
-var value;
+var poppedValue;
 return smalltalk.withContext(function($ctx1) { 
-value=self._pop();
+poppedValue=self._pop();
 self._pop();
-self._push_(value);
-self._assign_to_(_st(aNode)._left(),value);
-return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode,value:value},smalltalk.Interpreter)})},
+self._push_(poppedValue);
+self._assign_to_(_st(aNode)._left(),poppedValue);
+return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode,poppedValue:poppedValue},smalltalk.Interpreter)})},
 args: ["aNode"],
-source: "visitAssignmentNode: aNode\x0a\x09| value |\x0a\x09\x0a\x09value := self pop.\x0a\x09\x0a\x09\x22Pop the left side of the assignment.\x0a\x09It already has been visited, and we don't need its value.\x22\x0a\x09self pop.\x0a\x09\x0a\x09self push: value.\x0a\x09self assign: aNode left to: value",
+source: "visitAssignmentNode: aNode\x0a\x09| poppedValue |\x0a\x09\x0a\x09poppedValue := self pop.\x0a\x09\x0a\x09\x22Pop the left side of the assignment.\x0a\x09It already has been visited, and we don't need its value.\x22\x0a\x09self pop.\x0a\x09\x0a\x09self push: poppedValue.\x0a\x09self assign: aNode left to: poppedValue",
 messageSends: ["pop", "push:", "assign:to:", "left"],
 referencedClasses: []
 }),

+ 12 - 11
js/Compiler-Semantic.deploy.js

@@ -387,7 +387,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.LexicalScope.fn.prototype._allVariableNames.apply(_st(self), [])).__comma(_st(self._iVars())._keys());
+$1=_st(smalltalk.MethodLexicalScope.superclass.fn.prototype._allVariableNames.apply(_st(self), [])).__comma(_st(self._iVars())._keys());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"allVariableNames",{},smalltalk.MethodLexicalScope)})},
 messageSends: [",", "allVariableNames", "keys", "iVars"]}),
@@ -400,7 +400,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=smalltalk.LexicalScope.fn.prototype._bindingFor_.apply(_st(self), [aNode]);
+$2=smalltalk.MethodLexicalScope.superclass.fn.prototype._bindingFor_.apply(_st(self), [aNode]);
 if(($receiver = $2) == nil || $receiver == undefined){
 $1=_st(self._iVars())._at_ifAbsent_(_st(aNode)._value(),(function(){
 return smalltalk.withContext(function($ctx2) {
@@ -969,11 +969,12 @@ selector: "errorUnknownVariable:",
 fn: function (aNode){
 var self=this;
 var identifier;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 function $UnknownVariableError(){return smalltalk.UnknownVariableError||(typeof UnknownVariableError=="undefined"?nil:UnknownVariableError)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
 identifier=_st(aNode)._value();
-$1=_st(_st(["jQuery", "window", "document", "process", "global"]._includes_(identifier))._not())._and_((function(){
+$1=_st(_st(_st(_st(_st($Smalltalk())._current())._globalJsVariables())._includes_(identifier))._not())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._isVariableGloballyUndefined_(identifier);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
@@ -986,7 +987,7 @@ $3;
 _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_st(aNode)._value());
 };
 return self}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier},smalltalk.SemanticAnalyzer)})},
-messageSends: ["value", "ifTrue:ifFalse:", "and:", "not", "includes:", "isVariableGloballyUndefined:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope"]}),
+messageSends: ["value", "ifTrue:ifFalse:", "and:", "not", "includes:", "globalJsVariables", "current", "isVariableGloballyUndefined:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope"]}),
 smalltalk.SemanticAnalyzer);
 
 smalltalk.addMethod(
@@ -1182,7 +1183,7 @@ selector: "visitAssignmentNode:",
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.NodeVisitor.fn.prototype._visitAssignmentNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitAssignmentNode_.apply(_st(self), [aNode]);
 _st(_st(aNode)._left())._beAssigned();
 return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 messageSends: ["visitAssignmentNode:", "beAssigned", "left"]}),
@@ -1203,7 +1204,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addArg_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-smalltalk.NodeVisitor.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
 self._popScope();
 return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 messageSends: ["pushScope:", "newBlockScope", "scope:", "node:", "blockIndex:", "nextBlockIndex", "do:", "parameters", "validateVariableScope:", "addArg:", "visitBlockNode:", "popScope"]}),
@@ -1216,7 +1217,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.NodeVisitor.fn.prototype._visitCascadeNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitCascadeNode_.apply(_st(self), [aNode]);
 $1=_st(_st(_st(aNode)._nodes())._first())._superSend();
 if(smalltalk.assert($1)){
 _st(_st(aNode)._nodes())._do_((function(each){
@@ -1264,7 +1265,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addArg_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
-smalltalk.NodeVisitor.fn.prototype._visitMethodNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitMethodNode_.apply(_st(self), [aNode]);
 $1=aNode;
 _st($1)._classReferences_(self._classReferences());
 _st($1)._messageSends_(_st(self._messageSends())._keys());
@@ -1288,7 +1289,7 @@ _st(self["@currentScope"])._localReturn_(true);
 } else {
 _st(_st(self["@currentScope"])._methodScope())._addNonLocalReturn_(self["@currentScope"]);
 };
-smalltalk.NodeVisitor.fn.prototype._visitReturnNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitReturnNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 messageSends: ["scope:", "ifTrue:ifFalse:", "isMethodScope", "localReturn:", "addNonLocalReturn:", "methodScope", "visitReturnNode:"]}),
 smalltalk.SemanticAnalyzer);
@@ -1324,7 +1325,7 @@ return _st($Set())._new();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,5)})}));
 _st(_st(self._messageSends())._at_(_st(aNode)._selector()))._add_(aNode);
 _st(aNode)._index_(_st(_st(self._messageSends())._at_(_st(aNode)._selector()))._size());
-smalltalk.NodeVisitor.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 messageSends: ["ifTrue:ifFalse:", "=", "value", "receiver", "superSend:", "value:", "at:ifAbsentPut:", "superSends", "selector", "new", "add:", "at:", "ifTrue:", "includes:", "inlinedSelectors", "shouldBeInlined:", "shouldBeAliased:", "messageSends", "index:", "size", "visitSendNode:"]}),
 smalltalk.SemanticAnalyzer);
@@ -1340,7 +1341,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addTemp_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-smalltalk.NodeVisitor.fn.prototype._visitSequenceNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitSequenceNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 messageSends: ["do:", "temps", "validateVariableScope:", "addTemp:", "visitSequenceNode:"]}),
 smalltalk.SemanticAnalyzer);

+ 14 - 13
js/Compiler-Semantic.js

@@ -515,7 +515,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.LexicalScope.fn.prototype._allVariableNames.apply(_st(self), [])).__comma(_st(self._iVars())._keys());
+$1=_st(smalltalk.MethodLexicalScope.superclass.fn.prototype._allVariableNames.apply(_st(self), [])).__comma(_st(self._iVars())._keys());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"allVariableNames",{},smalltalk.MethodLexicalScope)})},
 args: [],
@@ -533,7 +533,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=smalltalk.LexicalScope.fn.prototype._bindingFor_.apply(_st(self), [aNode]);
+$2=smalltalk.MethodLexicalScope.superclass.fn.prototype._bindingFor_.apply(_st(self), [aNode]);
 if(($receiver = $2) == nil || $receiver == undefined){
 $1=_st(self._iVars())._at_ifAbsent_(_st(aNode)._value(),(function(){
 return smalltalk.withContext(function($ctx2) {
@@ -1306,11 +1306,12 @@ category: 'error handling',
 fn: function (aNode){
 var self=this;
 var identifier;
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 function $UnknownVariableError(){return smalltalk.UnknownVariableError||(typeof UnknownVariableError=="undefined"?nil:UnknownVariableError)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
 identifier=_st(aNode)._value();
-$1=_st(_st(["jQuery", "window", "document", "process", "global"]._includes_(identifier))._not())._and_((function(){
+$1=_st(_st(_st(_st(_st($Smalltalk())._current())._globalJsVariables())._includes_(identifier))._not())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._isVariableGloballyUndefined_(identifier);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
@@ -1324,9 +1325,9 @@ _st(_st(_st(self["@currentScope"])._methodScope())._unknownVariables())._add_(_s
 };
 return self}, function($ctx1) {$ctx1.fill(self,"errorUnknownVariable:",{aNode:aNode,identifier:identifier},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
-source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow four variable names in addition: `jQuery`, `window`, `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09\x0a\x09((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not\x0a\x09\x09and: [ self isVariableGloballyUndefined: identifier ])\x0a\x09\x09\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:", "and:", "not", "includes:", "isVariableGloballyUndefined:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope"],
-referencedClasses: ["UnknownVariableError"]
+source: "errorUnknownVariable: aNode\x0a\x09\x22Throw an error if the variable is undeclared in the global JS scope (i.e. window).\x0a\x09We allow all variables listed by Smalltalk>>#globalJsVariables.\x0a\x09This list includes: `jQuery`, `window`, `document`,  `process` and `global`\x0a\x09for nodejs and browser environments.\x0a\x09\x0a\x09This is only to make sure compilation works on both browser-based and nodejs environments.\x0a\x09The ideal solution would be to use a pragma instead\x22\x0a\x0a\x09| identifier |\x0a\x09identifier := aNode value.\x0a\x09\x0a\x09((Smalltalk current globalJsVariables includes: identifier) not\x0a\x09\x09and: [ self isVariableGloballyUndefined: identifier ])\x0a\x09\x09\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:", "and:", "not", "includes:", "globalJsVariables", "current", "isVariableGloballyUndefined:", "variableName:", "new", "signal", "add:", "unknownVariables", "methodScope"],
+referencedClasses: ["Smalltalk", "UnknownVariableError"]
 }),
 smalltalk.SemanticAnalyzer);
 
@@ -1584,7 +1585,7 @@ category: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.NodeVisitor.fn.prototype._visitAssignmentNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitAssignmentNode_.apply(_st(self), [aNode]);
 _st(_st(aNode)._left())._beAssigned();
 return self}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
@@ -1610,7 +1611,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addArg_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-smalltalk.NodeVisitor.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitBlockNode_.apply(_st(self), [aNode]);
 self._popScope();
 return self}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
@@ -1628,7 +1629,7 @@ fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.NodeVisitor.fn.prototype._visitCascadeNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitCascadeNode_.apply(_st(self), [aNode]);
 $1=_st(_st(_st(aNode)._nodes())._first())._superSend();
 if(smalltalk.assert($1)){
 _st(_st(aNode)._nodes())._do_((function(each){
@@ -1686,7 +1687,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addArg_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
-smalltalk.NodeVisitor.fn.prototype._visitMethodNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitMethodNode_.apply(_st(self), [aNode]);
 $1=aNode;
 _st($1)._classReferences_(self._classReferences());
 _st($1)._messageSends_(_st(self._messageSends())._keys());
@@ -1715,7 +1716,7 @@ _st(self["@currentScope"])._localReturn_(true);
 } else {
 _st(_st(self["@currentScope"])._methodScope())._addNonLocalReturn_(self["@currentScope"]);
 };
-smalltalk.NodeVisitor.fn.prototype._visitReturnNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitReturnNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
 source: "visitReturnNode: aNode\x0a\x09aNode scope: currentScope.\x0a\x09currentScope isMethodScope\x0a\x09\x09ifTrue: [ currentScope localReturn: true ]\x0a\x09\x09ifFalse: [ currentScope methodScope addNonLocalReturn: currentScope ].\x0a\x09super visitReturnNode: aNode",
@@ -1756,7 +1757,7 @@ return _st($Set())._new();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,5)})}));
 _st(_st(self._messageSends())._at_(_st(aNode)._selector()))._add_(aNode);
 _st(aNode)._index_(_st(_st(self._messageSends())._at_(_st(aNode)._selector()))._size());
-smalltalk.NodeVisitor.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitSendNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
 source: "visitSendNode: aNode\x0a\x0a\x09aNode receiver value = 'super'\x0a\x09\x09ifTrue: [\x0a\x09\x09\x09aNode superSend: true.\x0a\x09\x09\x09aNode receiver value: 'self'.\x0a\x09\x09\x09self superSends at: aNode selector ifAbsentPut: [ Set new ].\x0a\x09\x09\x09(self superSends at: aNode selector) add: aNode ]\x0a\x09\x09\x0a\x09\x09ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [\x0a\x09\x09\x09aNode shouldBeInlined: true.\x0a\x09\x09\x09aNode receiver shouldBeAliased: true ] ].\x0a\x0a\x09self messageSends at: aNode selector ifAbsentPut: [ Set new ].\x0a\x09(self messageSends at: aNode selector) add: aNode.\x0a\x0a\x09aNode index: (self messageSends at: aNode selector) size.\x0a\x0a\x09super visitSendNode: aNode",
@@ -1777,7 +1778,7 @@ return smalltalk.withContext(function($ctx2) {
 self._validateVariableScope_(each);
 return _st(self["@currentScope"])._addTemp_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-smalltalk.NodeVisitor.fn.prototype._visitSequenceNode_.apply(_st(self), [aNode]);
+smalltalk.SemanticAnalyzer.superclass.fn.prototype._visitSequenceNode_.apply(_st(self), [aNode]);
 return self}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
 source: "visitSequenceNode: aNode\x0a\x09aNode temps do: [ :each |\x0a\x09\x09self validateVariableScope: each.\x0a\x09\x09currentScope addTemp: each ].\x0a\x0a\x09super visitSequenceNode: aNode",

+ 1 - 1
js/Examples.deploy.js

@@ -36,7 +36,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Counter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@count"]=(0);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Counter)})},
 messageSends: ["initialize"]}),

+ 1 - 1
js/Examples.js

@@ -48,7 +48,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Counter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@count"]=(0);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Counter)})},
 args: [],

+ 10 - 10
js/Helios-Browser.deploy.js

@@ -208,7 +208,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLBrowser.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st([self._packagesListWidget(),self._classesListWidget(),self._protocolsListWidget(),self._methodsListWidget(),self._sourceWidget()])._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._unregister();
@@ -1321,7 +1321,7 @@ selector: "renderItem:on:",
 fn: function (aClass,html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLToolListWidget.fn.prototype._renderItem_on_.apply(_st(self), [aClass,html]);
+smalltalk.HLClassesListWidget.superclass.fn.prototype._renderItem_on_.apply(_st(self), [aClass,html]);
 _st(self._getChildrenOf_(aClass))._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._renderItem_level_on_(each,(1),html);
@@ -1815,7 +1815,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLDocumentationWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(_st(self._model())._announcer())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLDocumentationWidget)})},
 messageSends: ["unregister", "unregister:", "announcer", "model"]}),
@@ -2221,13 +2221,13 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=_st(self._model())._showInstance();
 if(smalltalk.assert($1)){
-smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLMethodsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 } else {
 $2=_st(html)._div();
 _st($2)._class_("class_side");
 $3=_st($2)._with_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+return smalltalk.HLMethodsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 $3;
 };
@@ -2723,13 +2723,13 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=_st(self._model())._showInstance();
 if(smalltalk.assert($1)){
-smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLProtocolsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 } else {
 $2=_st(html)._div();
 _st($2)._class_("class_side");
 $3=_st($2)._with_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+return smalltalk.HLProtocolsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 $3;
 };
@@ -2755,7 +2755,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HLToolListWidget.fn.prototype._selectedItem.apply(_st(self), []);
+$1=smalltalk.HLProtocolsListWidget.superclass.fn.prototype._selectedItem.apply(_st(self), []);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selectedItem",{},smalltalk.HLProtocolsListWidget)})},
 messageSends: ["selectedItem"]}),
@@ -2846,7 +2846,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLSelectorsCache.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._observeSystem();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLSelectorsCache)})},
 messageSends: ["initialize", "observeSystem"]}),
@@ -2953,7 +2953,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.HLSelectorsCache.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;

+ 10 - 10
js/Helios-Browser.js

@@ -270,7 +270,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLBrowser.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st([self._packagesListWidget(),self._classesListWidget(),self._protocolsListWidget(),self._methodsListWidget(),self._sourceWidget()])._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._unregister();
@@ -1715,7 +1715,7 @@ category: 'rendering',
 fn: function (aClass,html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLToolListWidget.fn.prototype._renderItem_on_.apply(_st(self), [aClass,html]);
+smalltalk.HLClassesListWidget.superclass.fn.prototype._renderItem_on_.apply(_st(self), [aClass,html]);
 _st(self._getChildrenOf_(aClass))._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._renderItem_level_on_(each,(1),html);
@@ -2370,7 +2370,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLDocumentationWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(_st(self._model())._announcer())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLDocumentationWidget)})},
 args: [],
@@ -2882,13 +2882,13 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=_st(self._model())._showInstance();
 if(smalltalk.assert($1)){
-smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLMethodsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 } else {
 $2=_st(html)._div();
 _st($2)._class_("class_side");
 $3=_st($2)._with_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+return smalltalk.HLMethodsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 $3;
 };
@@ -3541,13 +3541,13 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=_st(self._model())._showInstance();
 if(smalltalk.assert($1)){
-smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLProtocolsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 } else {
 $2=_st(html)._div();
 _st($2)._class_("class_side");
 $3=_st($2)._with_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+return smalltalk.HLProtocolsListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 $3;
 };
@@ -3583,7 +3583,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HLToolListWidget.fn.prototype._selectedItem.apply(_st(self), []);
+$1=smalltalk.HLProtocolsListWidget.superclass.fn.prototype._selectedItem.apply(_st(self), []);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selectedItem",{},smalltalk.HLProtocolsListWidget)})},
 args: [],
@@ -3699,7 +3699,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLSelectorsCache.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._observeSystem();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLSelectorsCache)})},
 args: [],
@@ -3846,7 +3846,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.HLSelectorsCache.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;

+ 13 - 13
js/Helios-Core.deploy.js

@@ -1671,7 +1671,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLFocusableWidget.fn.prototype._focus.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._focus.apply(_st(self), []);
 $1=_st(self._items())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=self._selectedItem();
@@ -1692,7 +1692,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@mapping"]=_st($Dictionary())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLListWidget)})},
 messageSends: ["initialize", "new"]}),
@@ -1768,7 +1768,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 var $early={};
 try {
-smalltalk.HLFocusableWidget.fn.prototype._refresh.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._refresh.apply(_st(self), []);
 self._ensureVisible_(_st(_st(self["@mapping"])._at_ifAbsent_(self._selectedItem(),(function(){
 return smalltalk.withContext(function($ctx2) {
 $1=self;
@@ -2042,7 +2042,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLListWidget.fn.prototype._setupKeyBindings.apply(_st(self), []);
+smalltalk.HLNavigationListWidget.superclass.fn.prototype._setupKeyBindings.apply(_st(self), []);
 _st(_st(self._wrapper())._asJQuery())._keydown_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(e)._which()).__eq((39));
@@ -2069,7 +2069,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLToolListWidget)})},
 messageSends: ["withChangesDo:", "model", "activateListItem:"]}),
@@ -2083,7 +2083,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activateNextListItem.apply(_st(self), []);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activateNextListItem.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLToolListWidget)})},
 messageSends: ["withChangesDo:", "model", "activateNextListItem"]}),
@@ -2097,7 +2097,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activatePreviousListItem.apply(_st(self), []);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activatePreviousListItem.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activatePreviousListItem",{},smalltalk.HLToolListWidget)})},
 messageSends: ["withChangesDo:", "model", "activatePreviousListItem"]}),
@@ -2211,7 +2211,7 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLToolListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLToolListWidget)})},
 messageSends: ["renderHeadOn:", "renderContentOn:"]}),
 smalltalk.HLToolListWidget);
@@ -2290,7 +2290,7 @@ selector: "selectedItem:",
 fn: function (anItem){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._selectedItem_.apply(_st(self), [anItem]);
+smalltalk.HLToolListWidget.superclass.fn.prototype._selectedItem_.apply(_st(self), [anItem]);
 self._updateMenu();
 return self}, function($ctx1) {$ctx1.fill(self,"selectedItem:",{anItem:anItem},smalltalk.HLToolListWidget)})},
 messageSends: ["selectedItem:", "updateMenu"]}),
@@ -2302,7 +2302,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLToolListWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(_st(self._model())._announcer())._unsubscribe_(self);
 _st(_st(self._model())._systemAnnouncer())._unsubscribe_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLToolListWidget)})},
@@ -2532,7 +2532,7 @@ function $HLInspector(){return smalltalk.HLInspector||(typeof HLInspector=="unde
 function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
 function $ProgressHandler(){return smalltalk.ProgressHandler||(typeof ProgressHandler=="undefined"?nil:ProgressHandler)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLManager.superclass.fn.prototype._initialize.apply(_st(self), []);
 _st($HLErrorHandler())._register();
 _st($HLProgressHandler())._register();
 self._registerInspector_($HLInspector());
@@ -3228,7 +3228,7 @@ selector: "renderMainOn:",
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLConfirmationWidget.fn.prototype._renderMainOn_.apply(_st(self), [html]);
+smalltalk.HLRequestWidget.superclass.fn.prototype._renderMainOn_.apply(_st(self), [html]);
 self["@input"]=_st(html)._textarea();
 _st(_st(self["@input"])._asJQuery())._val_(self._value());
 return self}, function($ctx1) {$ctx1.fill(self,"renderMainOn:",{html:html},smalltalk.HLRequestWidget)})},
@@ -3365,7 +3365,7 @@ $1=self._isVisible();
 if(smalltalk.assert($1)){
 self["@visible"]=false;
 self["@visible"];
-smalltalk.HLModalWidget.fn.prototype._remove.apply(_st(self), []);
+smalltalk.HLProgressWidget.superclass.fn.prototype._remove.apply(_st(self), []);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLProgressWidget)})},
 messageSends: ["ifTrue:", "isVisible", "remove"]}),

+ 13 - 13
js/Helios-Core.js

@@ -2218,7 +2218,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLFocusableWidget.fn.prototype._focus.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._focus.apply(_st(self), []);
 $1=_st(self._items())._isEmpty();
 if(! smalltalk.assert($1)){
 $2=self._selectedItem();
@@ -2244,7 +2244,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@mapping"]=_st($Dictionary())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLListWidget)})},
 args: [],
@@ -2345,7 +2345,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 var $early={};
 try {
-smalltalk.HLFocusableWidget.fn.prototype._refresh.apply(_st(self), []);
+smalltalk.HLListWidget.superclass.fn.prototype._refresh.apply(_st(self), []);
 self._ensureVisible_(_st(_st(self["@mapping"])._at_ifAbsent_(self._selectedItem(),(function(){
 return smalltalk.withContext(function($ctx2) {
 $1=self;
@@ -2704,7 +2704,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLListWidget.fn.prototype._setupKeyBindings.apply(_st(self), []);
+smalltalk.HLNavigationListWidget.superclass.fn.prototype._setupKeyBindings.apply(_st(self), []);
 _st(_st(self._wrapper())._asJQuery())._keydown_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(e)._which()).__eq((39));
@@ -2736,7 +2736,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLToolListWidget)})},
 args: ["anItem"],
@@ -2755,7 +2755,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activateNextListItem.apply(_st(self), []);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activateNextListItem.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateNextListItem",{},smalltalk.HLToolListWidget)})},
 args: [],
@@ -2774,7 +2774,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLNavigationListWidget.fn.prototype._activatePreviousListItem.apply(_st(self), []);
+return smalltalk.HLToolListWidget.superclass.fn.prototype._activatePreviousListItem.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activatePreviousListItem",{},smalltalk.HLToolListWidget)})},
 args: [],
@@ -2928,7 +2928,7 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLToolListWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLToolListWidget)})},
 args: ["html"],
 source: "renderContentOn: html\x0a\x09self renderHeadOn: html.\x09\x0a\x09super renderContentOn: html",
@@ -3022,7 +3022,7 @@ category: 'accessing',
 fn: function (anItem){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._selectedItem_.apply(_st(self), [anItem]);
+smalltalk.HLToolListWidget.superclass.fn.prototype._selectedItem_.apply(_st(self), [anItem]);
 self._updateMenu();
 return self}, function($ctx1) {$ctx1.fill(self,"selectedItem:",{anItem:anItem},smalltalk.HLToolListWidget)})},
 args: ["anItem"],
@@ -3039,7 +3039,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLToolListWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(_st(self._model())._announcer())._unsubscribe_(self);
 _st(_st(self._model())._systemAnnouncer())._unsubscribe_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLToolListWidget)})},
@@ -3339,7 +3339,7 @@ function $HLInspector(){return smalltalk.HLInspector||(typeof HLInspector=="unde
 function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
 function $ProgressHandler(){return smalltalk.ProgressHandler||(typeof ProgressHandler=="undefined"?nil:ProgressHandler)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLManager.superclass.fn.prototype._initialize.apply(_st(self), []);
 _st($HLErrorHandler())._register();
 _st($HLProgressHandler())._register();
 self._registerInspector_($HLInspector());
@@ -4238,7 +4238,7 @@ category: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLConfirmationWidget.fn.prototype._renderMainOn_.apply(_st(self), [html]);
+smalltalk.HLRequestWidget.superclass.fn.prototype._renderMainOn_.apply(_st(self), [html]);
 self["@input"]=_st(html)._textarea();
 _st(_st(self["@input"])._asJQuery())._val_(self._value());
 return self}, function($ctx1) {$ctx1.fill(self,"renderMainOn:",{html:html},smalltalk.HLRequestWidget)})},
@@ -4416,7 +4416,7 @@ $1=self._isVisible();
 if(smalltalk.assert($1)){
 self["@visible"]=false;
 self["@visible"];
-smalltalk.HLModalWidget.fn.prototype._remove.apply(_st(self), []);
+smalltalk.HLProgressWidget.superclass.fn.prototype._remove.apply(_st(self), []);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLProgressWidget)})},
 args: [],

+ 4 - 4
js/Helios-Debugger.deploy.js

@@ -247,7 +247,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLDebugger.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(self._inspectorWidget())._unregister();
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLDebugger)})},
 messageSends: ["unregister", "inspectorWidget"]}),
@@ -323,7 +323,7 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._clearHighlight();
-smalltalk.HLBrowserCodeWidget.fn.prototype._contents_.apply(_st(self), [aString]);
+smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._contents_.apply(_st(self), [aString]);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString},smalltalk.HLDebuggerCodeWidget)})},
 messageSends: ["clearHighlight", "contents:"]}),
 smalltalk.HLDebuggerCodeWidget);
@@ -335,7 +335,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
-$2=smalltalk.HLBrowserCodeWidget.fn.prototype._editorOptions.apply(_st(self), []);
+$2=smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._editorOptions.apply(_st(self), []);
 _st($2)._at_put_("gutters",["CodeMirror-linenumbers", "stops"]);
 $3=_st($2)._yourself();
 $1=$3;
@@ -388,7 +388,7 @@ function $HLDebuggerContextSelected(){return smalltalk.HLDebuggerContextSelected
 function $HLDebuggerStepped(){return smalltalk.HLDebuggerStepped||(typeof HLDebuggerStepped=="undefined"?nil:HLDebuggerStepped)}
 function $HLDebuggerWhere(){return smalltalk.HLDebuggerWhere||(typeof HLDebuggerWhere=="undefined"?nil:HLDebuggerWhere)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLBrowserCodeWidget.fn.prototype._observeBrowserModel.apply(_st(self), []);
+smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._observeBrowserModel.apply(_st(self), []);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerContextSelected(),"onContextSelected",self);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerStepped(),"onContextSelected",self);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerWhere(),"onContextSelected",self);

+ 4 - 4
js/Helios-Debugger.js

@@ -319,7 +319,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLFocusableWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLDebugger.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(self._inspectorWidget())._unregister();
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLDebugger)})},
 args: [],
@@ -425,7 +425,7 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._clearHighlight();
-smalltalk.HLBrowserCodeWidget.fn.prototype._contents_.apply(_st(self), [aString]);
+smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._contents_.apply(_st(self), [aString]);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString},smalltalk.HLDebuggerCodeWidget)})},
 args: ["aString"],
 source: "contents: aString\x0a\x09self clearHighlight.\x0a\x09super contents: aString",
@@ -442,7 +442,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
-$2=smalltalk.HLBrowserCodeWidget.fn.prototype._editorOptions.apply(_st(self), []);
+$2=smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._editorOptions.apply(_st(self), []);
 _st($2)._at_put_("gutters",["CodeMirror-linenumbers", "stops"]);
 $3=_st($2)._yourself();
 $1=$3;
@@ -510,7 +510,7 @@ function $HLDebuggerContextSelected(){return smalltalk.HLDebuggerContextSelected
 function $HLDebuggerStepped(){return smalltalk.HLDebuggerStepped||(typeof HLDebuggerStepped=="undefined"?nil:HLDebuggerStepped)}
 function $HLDebuggerWhere(){return smalltalk.HLDebuggerWhere||(typeof HLDebuggerWhere=="undefined"?nil:HLDebuggerWhere)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLBrowserCodeWidget.fn.prototype._observeBrowserModel.apply(_st(self), []);
+smalltalk.HLDebuggerCodeWidget.superclass.fn.prototype._observeBrowserModel.apply(_st(self), []);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerContextSelected(),"onContextSelected",self);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerStepped(),"onContextSelected",self);
 _st(_st(self._browserModel())._announcer())._on_send_to_($HLDebuggerWhere(),"onContextSelected",self);

+ 8 - 11
js/Helios-Inspector.deploy.js

@@ -429,7 +429,7 @@ var $1;
 $1=_st(self._variables()).__eq(self._items());
 if(! smalltalk.assert($1)){
 self._resetItems();
-smalltalk.HLNavigationListWidget.fn.prototype._refresh.apply(_st(self), []);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._refresh.apply(_st(self), []);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLInspectorVariablesWidget)})},
 messageSends: ["ifFalse:", "=", "variables", "items", "resetItems", "refresh"]}),
@@ -462,7 +462,7 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLInspectorVariablesWidget)})},
 messageSends: ["renderHeadOn:", "renderContentOn:"]}),
 smalltalk.HLInspectorVariablesWidget);
@@ -498,7 +498,7 @@ selector: "selectItem:",
 fn: function (anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._selectItem_.apply(_st(self), [anObject]);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._selectItem_.apply(_st(self), [anObject]);
 _st(self._model())._selectedInstVar_(anObject);
 return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{anObject:anObject},smalltalk.HLInspectorVariablesWidget)})},
 messageSends: ["selectItem:", "selectedInstVar:", "model"]}),
@@ -586,7 +586,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLInspectorWidget.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._register();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLInspectorWidget)})},
 messageSends: ["initialize", "register"]}),
@@ -787,12 +787,9 @@ selector: "refresh",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-$1=self;
-_st($1)._refreshVariablesWidget();
-$2=_st($1)._refreshDisplayWidget();
+self._inspect_(self._inspectee());
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLInspectorWidget)})},
-messageSends: ["refreshVariablesWidget", "refreshDisplayWidget"]}),
+messageSends: ["inspect:", "inspectee"]}),
 smalltalk.HLInspectorWidget);
 
 smalltalk.addMethod(
@@ -882,7 +879,7 @@ fn: function (){
 var self=this;
 function $HLInspector(){return smalltalk.HLInspector||(typeof HLInspector=="undefined"?nil:HLInspector)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLInspectorWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st($HLInspector())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLInspectorWidget)})},
 messageSends: ["unregister", "unregister:"]}),
@@ -948,7 +945,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLInspectorWidget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLInspector.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._watchChanges();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLInspector.klass)})},
 messageSends: ["initialize", "watchChanges"]}),

+ 9 - 12
js/Helios-Inspector.js

@@ -570,7 +570,7 @@ var $1;
 $1=_st(self._variables()).__eq(self._items());
 if(! smalltalk.assert($1)){
 self._resetItems();
-smalltalk.HLNavigationListWidget.fn.prototype._refresh.apply(_st(self), []);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._refresh.apply(_st(self), []);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLInspectorVariablesWidget)})},
 args: [],
@@ -613,7 +613,7 @@ fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._renderHeadOn_(html);
-smalltalk.HLNavigationListWidget.fn.prototype._renderContentOn_.apply(_st(self), [html]);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._renderContentOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLInspectorVariablesWidget)})},
 args: ["html"],
 source: "renderContentOn: html\x0a\x09self renderHeadOn: html.\x0a\x09super renderContentOn: html",
@@ -664,7 +664,7 @@ category: 'reactions',
 fn: function (anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationListWidget.fn.prototype._selectItem_.apply(_st(self), [anObject]);
+smalltalk.HLInspectorVariablesWidget.superclass.fn.prototype._selectItem_.apply(_st(self), [anObject]);
 _st(self._model())._selectedInstVar_(anObject);
 return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{anObject:anObject},smalltalk.HLInspectorVariablesWidget)})},
 args: ["anObject"],
@@ -777,7 +777,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLInspectorWidget.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._register();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLInspectorWidget)})},
 args: [],
@@ -1053,14 +1053,11 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-$1=self;
-_st($1)._refreshVariablesWidget();
-$2=_st($1)._refreshDisplayWidget();
+self._inspect_(self._inspectee());
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLInspectorWidget)})},
 args: [],
-source: "refresh\x0a\x09self \x0a\x09\x09refreshVariablesWidget;\x0a\x09\x09refreshDisplayWidget",
-messageSends: ["refreshVariablesWidget", "refreshDisplayWidget"],
+source: "refresh\x0a\x09self inspect: self inspectee",
+messageSends: ["inspect:", "inspectee"],
 referencedClasses: []
 }),
 smalltalk.HLInspectorWidget);
@@ -1188,7 +1185,7 @@ fn: function (){
 var self=this;
 function $HLInspector(){return smalltalk.HLInspector||(typeof HLInspector=="undefined"?nil:HLInspector)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLInspectorWidget.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st($HLInspector())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLInspectorWidget)})},
 args: [],
@@ -1274,7 +1271,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLInspectorWidget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLInspector.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._watchChanges();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLInspector.klass)})},
 args: [],

+ 4 - 4
js/Helios-KeyBindings.deploy.js

@@ -428,7 +428,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLBinding.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
+$1=_st(smalltalk.HLBindingGroup.superclass.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBindingGroup)})},
 messageSends: [",", "displayLabel"]}),
@@ -702,7 +702,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@isFinal"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@isFinal"]=smalltalk.HLBinding.fn.prototype._isFinal.apply(_st(self), []);
+self["@isFinal"]=smalltalk.HLBindingInput.superclass.fn.prototype._isFinal.apply(_st(self), []);
 $1=self["@isFinal"];
 } else {
 $1=$2;
@@ -1103,7 +1103,7 @@ var self=this;
 function $HLKeyBinderHelper(){return smalltalk.HLKeyBinderHelper||(typeof HLKeyBinderHelper=="undefined"?nil:HLKeyBinderHelper)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLKeyBinder.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@helper"]=_st($HLKeyBinderHelper())._on_(self);
 $1=self["@helper"];
 _st($1)._renderStart();
@@ -1570,7 +1570,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLRepeatingKeyBindingHandler.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@keyBindings"]=_st($Dictionary())._new();
 self["@isKeyCurrentlyPressed"]=false;
 self["@repeatInterval"]=(70);

+ 4 - 4
js/Helios-KeyBindings.js

@@ -569,7 +569,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLBinding.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
+$1=_st(smalltalk.HLBindingGroup.superclass.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBindingGroup)})},
 args: [],
@@ -938,7 +938,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@isFinal"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@isFinal"]=smalltalk.HLBinding.fn.prototype._isFinal.apply(_st(self), []);
+self["@isFinal"]=smalltalk.HLBindingInput.superclass.fn.prototype._isFinal.apply(_st(self), []);
 $1=self["@isFinal"];
 } else {
 $1=$2;
@@ -1454,7 +1454,7 @@ var self=this;
 function $HLKeyBinderHelper(){return smalltalk.HLKeyBinderHelper||(typeof HLKeyBinderHelper=="undefined"?nil:HLKeyBinderHelper)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLKeyBinder.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@helper"]=_st($HLKeyBinderHelper())._on_(self);
 $1=self["@helper"];
 _st($1)._renderStart();
@@ -2067,7 +2067,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLRepeatingKeyBindingHandler.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@keyBindings"]=_st($Dictionary())._new();
 self["@isKeyCurrentlyPressed"]=false;
 self["@repeatInterval"]=(70);

+ 4 - 4
js/Helios-Layout.deploy.js

@@ -214,7 +214,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLHorizontalSplitter)})},
 messageSends: [",", "cssClass"]}),
@@ -227,7 +227,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLHorizontalSplitter)})},
 messageSends: [",", "panesCssClass"]}),
@@ -301,7 +301,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLVerticalSplitter)})},
 messageSends: [",", "cssClass"]}),
@@ -314,7 +314,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLVerticalSplitter)})},
 messageSends: [",", "panesCssClass"]}),

+ 4 - 4
js/Helios-Layout.js

@@ -290,7 +290,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLHorizontalSplitter)})},
 args: [],
@@ -308,7 +308,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLHorizontalSplitter)})},
 args: [],
@@ -407,7 +407,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLVerticalSplitter)})},
 args: [],
@@ -425,7 +425,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLSplitter.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLVerticalSplitter)})},
 args: [],

+ 1 - 1
js/Helios-References.deploy.js

@@ -341,7 +341,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+return smalltalk.HLReferencesListWidget.superclass.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLReferencesListWidget)})},
 messageSends: ["withChangesDo:", "model", "activateListItem:"]}),

+ 1 - 1
js/Helios-References.js

@@ -452,7 +452,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HLToolListWidget.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
+return smalltalk.HLReferencesListWidget.superclass.fn.prototype._activateListItem_.apply(_st(self), [anItem]);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"activateListItem:",{anItem:anItem},smalltalk.HLReferencesListWidget)})},
 args: ["anItem"],

+ 2 - 2
js/Helios-Transcript.deploy.js

@@ -17,7 +17,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLTranscript.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._register();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLTranscript)})},
 messageSends: ["initialize", "register"]}),
@@ -77,7 +77,7 @@ fn: function (){
 var self=this;
 function $HLTranscriptHandler(){return smalltalk.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLTranscript.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st($HLTranscriptHandler())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLTranscript)})},
 messageSends: ["unregister", "unregister:"]}),

+ 2 - 2
js/Helios-Transcript.js

@@ -24,7 +24,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLTranscript.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._register();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLTranscript)})},
 args: [],
@@ -104,7 +104,7 @@ fn: function (){
 var self=this;
 function $HLTranscriptHandler(){return smalltalk.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLTranscript.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st($HLTranscriptHandler())._unregister_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLTranscript)})},
 args: [],

+ 6 - 6
js/Helios-Workspace.deploy.js

@@ -738,7 +738,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLWidget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLCodeWidget.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self;
 _st($1)._setupCodeMirror();
 _st($1)._setupCommands();
@@ -882,7 +882,7 @@ selector: "configureEditor",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLCodeWidget.fn.prototype._configureEditor.apply(_st(self), []);
+smalltalk.HLNavigationCodeWidget.superclass.fn.prototype._configureEditor.apply(_st(self), []);
 self._contents_(self._methodContents());
 return self}, function($ctx1) {$ctx1.fill(self,"configureEditor",{},smalltalk.HLNavigationCodeWidget)})},
 messageSends: ["configureEditor", "contents:", "methodContents"]}),
@@ -895,7 +895,7 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._methodContents_(aString);
-smalltalk.HLCodeWidget.fn.prototype._contents_.apply(_st(self), [aString]);
+smalltalk.HLNavigationCodeWidget.superclass.fn.prototype._contents_.apply(_st(self), [aString]);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString},smalltalk.HLNavigationCodeWidget)})},
 messageSends: ["methodContents:", "contents:"]}),
 smalltalk.HLNavigationCodeWidget);
@@ -1357,7 +1357,7 @@ $2=_st($1)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._saveIt();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
-smalltalk.HLNavigationCodeWidget.fn.prototype._renderButtonsOn_.apply(_st(self), [html]);
+smalltalk.HLBrowserCodeWidget.superclass.fn.prototype._renderButtonsOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderButtonsOn:",{html:html},smalltalk.HLBrowserCodeWidget)})},
 messageSends: ["class:", "button", "with:", "onClick:", "saveIt", "renderButtonsOn:"]}),
 smalltalk.HLBrowserCodeWidget);
@@ -1379,7 +1379,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationCodeWidget.fn.prototype._unregsiter.apply(_st(self), []);
+smalltalk.HLBrowserCodeWidget.superclass.fn.prototype._unregsiter.apply(_st(self), []);
 _st(_st(self._browserModel())._announcer())._unsubscribe_(self);
 _st(_st(self._browserModel())._systemAnnouncer())._unsubscribe_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLBrowserCodeWidget)})},
@@ -1523,7 +1523,7 @@ selector: "unregister",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLWorkspace.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(self._transcript())._unregister();
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLWorkspace)})},
 messageSends: ["unregister", "transcript"]}),

+ 6 - 6
js/Helios-Workspace.js

@@ -979,7 +979,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.HLWidget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.HLCodeWidget.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 $1=self;
 _st($1)._setupCodeMirror();
 _st($1)._setupCommands();
@@ -1168,7 +1168,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLCodeWidget.fn.prototype._configureEditor.apply(_st(self), []);
+smalltalk.HLNavigationCodeWidget.superclass.fn.prototype._configureEditor.apply(_st(self), []);
 self._contents_(self._methodContents());
 return self}, function($ctx1) {$ctx1.fill(self,"configureEditor",{},smalltalk.HLNavigationCodeWidget)})},
 args: [],
@@ -1186,7 +1186,7 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._methodContents_(aString);
-smalltalk.HLCodeWidget.fn.prototype._contents_.apply(_st(self), [aString]);
+smalltalk.HLNavigationCodeWidget.superclass.fn.prototype._contents_.apply(_st(self), [aString]);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString},smalltalk.HLNavigationCodeWidget)})},
 args: ["aString"],
 source: "contents: aString\x0a\x09self methodContents: aString.\x0a\x09super contents: aString",
@@ -1778,7 +1778,7 @@ $2=_st($1)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._saveIt();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
-smalltalk.HLNavigationCodeWidget.fn.prototype._renderButtonsOn_.apply(_st(self), [html]);
+smalltalk.HLBrowserCodeWidget.superclass.fn.prototype._renderButtonsOn_.apply(_st(self), [html]);
 return self}, function($ctx1) {$ctx1.fill(self,"renderButtonsOn:",{html:html},smalltalk.HLBrowserCodeWidget)})},
 args: ["html"],
 source: "renderButtonsOn: html\x0a\x09html button \x0a\x09\x09class: 'button';\x0a\x09\x09with: 'SaveIt';\x0a\x09\x09onClick: [ self saveIt ].\x0a\x09super renderButtonsOn: html",
@@ -1810,7 +1810,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLNavigationCodeWidget.fn.prototype._unregsiter.apply(_st(self), []);
+smalltalk.HLBrowserCodeWidget.superclass.fn.prototype._unregsiter.apply(_st(self), []);
 _st(_st(self._browserModel())._announcer())._unsubscribe_(self);
 _st(_st(self._browserModel())._systemAnnouncer())._unsubscribe_(self);
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLBrowserCodeWidget)})},
@@ -1999,7 +1999,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLWidget.fn.prototype._unregister.apply(_st(self), []);
+smalltalk.HLWorkspace.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st(self._transcript())._unregister();
 return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLWorkspace)})},
 args: [],

+ 10 - 10
js/IDE.deploy.js

@@ -743,7 +743,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Widget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.SourceArea.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._setupCodeMirror();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.SourceArea.klass)})},
 messageSends: ["initialize", "setupCodeMirror"]}),
@@ -820,7 +820,7 @@ function $Workspace(){return smalltalk.Workspace||(typeof Workspace=="undefined"
 function $TestRunner(){return smalltalk.TestRunner||(typeof TestRunner=="undefined"?nil:TestRunner)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6;
-smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TabManager.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@opened"]=true;
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
@@ -1199,7 +1199,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Widget.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.TabManager.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;
@@ -1869,7 +1869,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Browser.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@selectedTab"]="instance";
 self["@selectedPackage"]=_st(self._packages())._first();
 self["@unsavedChanges"]=false;
@@ -3077,7 +3077,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Debugger.superclass.fn.prototype._initialize.apply(_st(self), []);
 _st(self["@unsavedChanges"]).__eq(false);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Debugger)})},
 messageSends: ["initialize", "="]}),
@@ -3601,7 +3601,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.TabWidget.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.IDETranscript.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;
@@ -4165,7 +4165,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ReferencesBrowser.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@selector"]="";
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ReferencesBrowser)})},
 messageSends: ["initialize"]}),
@@ -4688,7 +4688,7 @@ fn: function (){
 var self=this;
 function $TestResult(){return smalltalk.TestResult||(typeof TestResult=="undefined"?nil:TestResult)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestRunner.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@result"]=_st($TestResult())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.TestRunner)})},
 messageSends: ["initialize", "new"]}),
@@ -5390,7 +5390,7 @@ selector: "show",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._show.apply(_st(self), []);
+smalltalk.Workspace.superclass.fn.prototype._show.apply(_st(self), []);
 _st(self["@sourceArea"])._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"show",{},smalltalk.Workspace)})},
 messageSends: ["show", "focus"]}),
@@ -5451,7 +5451,7 @@ var self=this;
 var label;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.CharacterArray.fn.prototype._inspectOn_.apply(_st(self), [anInspector]);
+smalltalk.String.superclass.fn.prototype._inspectOn_.apply(_st(self), [anInspector]);
 $1=_st(_st(self._printString())._size()).__gt((30));
 if(smalltalk.assert($1)){
 label=_st(_st(self._printString())._copyFrom_to_((1),(30))).__comma("...'");

+ 10 - 10
js/IDE.js

@@ -969,7 +969,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Widget.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.SourceArea.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._setupCodeMirror();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.SourceArea.klass)})},
 args: [],
@@ -1071,7 +1071,7 @@ function $Workspace(){return smalltalk.Workspace||(typeof Workspace=="undefined"
 function $TestRunner(){return smalltalk.TestRunner||(typeof TestRunner=="undefined"?nil:TestRunner)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6;
-smalltalk.Widget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TabManager.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@opened"]=true;
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
@@ -1545,7 +1545,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Widget.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.TabManager.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;
@@ -2405,7 +2405,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Browser.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@selectedTab"]="instance";
 self["@selectedPackage"]=_st(self._packages())._first();
 self["@unsavedChanges"]=false;
@@ -3838,7 +3838,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Debugger.superclass.fn.prototype._initialize.apply(_st(self), []);
 _st(self["@unsavedChanges"]).__eq(false);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Debugger)})},
 args: [],
@@ -4497,7 +4497,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.TabWidget.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.IDETranscript.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;
@@ -5226,7 +5226,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ReferencesBrowser.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@selector"]="";
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ReferencesBrowser)})},
 args: [],
@@ -5879,7 +5879,7 @@ fn: function (){
 var self=this;
 function $TestResult(){return smalltalk.TestResult||(typeof TestResult=="undefined"?nil:TestResult)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestRunner.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@result"]=_st($TestResult())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.TestRunner)})},
 args: [],
@@ -6781,7 +6781,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.TabWidget.fn.prototype._show.apply(_st(self), []);
+smalltalk.Workspace.superclass.fn.prototype._show.apply(_st(self), []);
 _st(self["@sourceArea"])._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"show",{},smalltalk.Workspace)})},
 args: [],
@@ -6857,7 +6857,7 @@ var self=this;
 var label;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.CharacterArray.fn.prototype._inspectOn_.apply(_st(self), [anInspector]);
+smalltalk.String.superclass.fn.prototype._inspectOn_.apply(_st(self), [anInspector]);
 $1=_st(_st(self._printString())._size()).__gt((30));
 if(smalltalk.assert($1)){
 label=_st(_st(self._printString())._copyFrom_to_((1),(30))).__comma("...'");

+ 2 - 2
js/Kernel-Announcements.deploy.js

@@ -147,7 +147,7 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Announcer.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@subscriptions"]=_st($OrderedCollection())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Announcer)})},
 messageSends: ["initialize", "new"]}),
@@ -220,7 +220,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Announcer.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.SystemAnnouncer.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;

+ 2 - 2
js/Kernel-Announcements.js

@@ -200,7 +200,7 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Announcer.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@subscriptions"]=_st($OrderedCollection())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Announcer)})},
 args: [],
@@ -294,7 +294,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@current"]=smalltalk.Announcer.klass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=smalltalk.SystemAnnouncer.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;

+ 18 - 3
js/Kernel-Classes.deploy.js

@@ -588,6 +588,20 @@ return self}, function($ctx1) {$ctx1.fill(self,"prototype",{},smalltalk.Behavior
 messageSends: []}),
 smalltalk.Behavior);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "recompile",
+fn: function (){
+var self=this;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st($Compiler())._new())._recompile_(self);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"recompile",{},smalltalk.Behavior)})},
+messageSends: ["recompile:", "new"]}),
+smalltalk.Behavior);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "removeCompiledMethod:",
@@ -1315,12 +1329,13 @@ function $ClassRenamed(){return smalltalk.ClassRenamed||(typeof ClassRenamed=="u
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 self._basicRenameClass_to_(aClass,className);
+_st(aClass)._recompile();
 $1=_st($ClassRenamed())._new();
 _st($1)._theClass_(aClass);
 $2=_st($1)._yourself();
 _st(_st($SystemAnnouncer())._current())._announce_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"renameClass:to:",{aClass:aClass,className:className},smalltalk.ClassBuilder)})},
-messageSends: ["basicRenameClass:to:", "announce:", "current", "theClass:", "new", "yourself"]}),
+messageSends: ["basicRenameClass:to:", "recompile", "announce:", "current", "theClass:", "new", "yourself"]}),
 smalltalk.ClassBuilder);
 
 smalltalk.addMethod(
@@ -1412,7 +1427,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ClassCategoryReader.superclass.fn.prototype._initialize.apply(_st(self), []);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ClassCategoryReader)})},
 messageSends: ["initialize"]}),
 smalltalk.ClassCategoryReader);
@@ -1459,7 +1474,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ClassCommentReader.superclass.fn.prototype._initialize.apply(_st(self), []);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ClassCommentReader)})},
 messageSends: ["initialize"]}),
 smalltalk.ClassCommentReader);

+ 24 - 4
js/Kernel-Classes.js

@@ -769,6 +769,25 @@ referencedClasses: []
 }),
 smalltalk.Behavior);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "recompile",
+category: 'compiling',
+fn: function (){
+var self=this;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st($Compiler())._new())._recompile_(self);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"recompile",{},smalltalk.Behavior)})},
+args: [],
+source: "recompile\x0a\x09^ Compiler new recompile: self",
+messageSends: ["recompile:", "new"],
+referencedClasses: ["Compiler"]
+}),
+smalltalk.Behavior);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "removeCompiledMethod:",
@@ -1715,14 +1734,15 @@ function $ClassRenamed(){return smalltalk.ClassRenamed||(typeof ClassRenamed=="u
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 self._basicRenameClass_to_(aClass,className);
+_st(aClass)._recompile();
 $1=_st($ClassRenamed())._new();
 _st($1)._theClass_(aClass);
 $2=_st($1)._yourself();
 _st(_st($SystemAnnouncer())._current())._announce_($2);
 return self}, function($ctx1) {$ctx1.fill(self,"renameClass:to:",{aClass:aClass,className:className},smalltalk.ClassBuilder)})},
 args: ["aClass", "className"],
-source: "renameClass: aClass to: className\x0a\x09self basicRenameClass: aClass to: className.\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (ClassRenamed new\x0a\x09\x09\x09theClass: aClass;\x0a\x09\x09\x09yourself)",
-messageSends: ["basicRenameClass:to:", "announce:", "current", "theClass:", "new", "yourself"],
+source: "renameClass: aClass to: className\x0a\x09self basicRenameClass: aClass to: className.\x0a\x09\x0a\x09\x22Recompile the class to fix potential issues with super sends\x22\x0a\x09aClass recompile.\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (ClassRenamed new\x0a\x09\x09\x09theClass: aClass;\x0a\x09\x09\x09yourself)",
+messageSends: ["basicRenameClass:to:", "recompile", "announce:", "current", "theClass:", "new", "yourself"],
 referencedClasses: ["SystemAnnouncer", "ClassRenamed"]
 }),
 smalltalk.ClassBuilder);
@@ -1843,7 +1863,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ClassCategoryReader.superclass.fn.prototype._initialize.apply(_st(self), []);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ClassCategoryReader)})},
 args: [],
 source: "initialize\x0a\x09super initialize.",
@@ -1906,7 +1926,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ClassCommentReader.superclass.fn.prototype._initialize.apply(_st(self), []);
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ClassCommentReader)})},
 args: [],
 source: "initialize\x0a\x09super initialize.",

+ 48 - 8
js/Kernel-Collections.deploy.js

@@ -864,7 +864,7 @@ fn: function (aHashedCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.IndexableCollection.fn.prototype._addAll_.apply(_st(self), [_st(aHashedCollection)._associations()]);
+smalltalk.HashedCollection.superclass.fn.prototype._addAll_.apply(_st(self), [_st(aHashedCollection)._associations()]);
 $1=aHashedCollection;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"addAll:",{aHashedCollection:aHashedCollection},smalltalk.HashedCollection)})},
@@ -1103,6 +1103,35 @@ return $1;
 messageSends: ["detect:ifNone:", "keys", "=", "at:"]}),
 smalltalk.HashedCollection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "keyAtValue:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._keyAtValue_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
+return self._errorNotFound();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"keyAtValue:",{anObject:anObject},smalltalk.HashedCollection)})},
+messageSends: ["keyAtValue:ifAbsent:", "errorNotFound"]}),
+smalltalk.HashedCollection);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "keyAtValue:ifAbsent:",
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._indexOf_ifAbsent_(anObject,aBlock);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"keyAtValue:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.HashedCollection)})},
+messageSends: ["indexOf:ifAbsent:"]}),
+smalltalk.HashedCollection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "keys",
@@ -1154,7 +1183,7 @@ selector: "printOn:",
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IndexableCollection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.HashedCollection.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 _st(self._associations())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -1469,7 +1498,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HashedCollection.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Dictionary.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@keys"]=[];
 self["@values"]=[];
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Dictionary)})},
@@ -2137,7 +2166,7 @@ selector: "printOn:",
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.SequenceableCollection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Array.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 self._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -2176,11 +2205,22 @@ selector: "removeFrom:to:",
 fn: function (aNumber,anotherNumber){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self.splice(aNumber - 1,anotherNumber - 1);
+self.splice(aNumber -1, anotherNumber - aNumber + 1);
 return self}, function($ctx1) {$ctx1.fill(self,"removeFrom:to:",{aNumber:aNumber,anotherNumber:anotherNumber},smalltalk.Array)})},
 messageSends: []}),
 smalltalk.Array);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "removeIndex:",
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self.splice(anInteger - 1, 1);
+return self}, function($ctx1) {$ctx1.fill(self,"removeIndex:",{anInteger:anInteger},smalltalk.Array)})},
+messageSends: []}),
+smalltalk.Array);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "removeLast",
@@ -3510,7 +3550,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Collection.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Set.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@elements"]=[];
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Set)})},
 messageSends: ["initialize"]}),
@@ -3522,7 +3562,7 @@ selector: "printOn:",
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Collection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Set.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 self._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -3603,7 +3643,7 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Queue.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@read"]=_st($OrderedCollection())._new();
 self["@write"]=_st($OrderedCollection())._new();
 self["@readIndex"]=(1);

+ 65 - 10
js/Kernel-Collections.js

@@ -1149,7 +1149,7 @@ fn: function (aHashedCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.IndexableCollection.fn.prototype._addAll_.apply(_st(self), [_st(aHashedCollection)._associations()]);
+smalltalk.HashedCollection.superclass.fn.prototype._addAll_.apply(_st(self), [_st(aHashedCollection)._associations()]);
 $1=aHashedCollection;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"addAll:",{aHashedCollection:aHashedCollection},smalltalk.HashedCollection)})},
@@ -1467,6 +1467,45 @@ referencedClasses: []
 }),
 smalltalk.HashedCollection);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "keyAtValue:",
+category: 'accessing',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._keyAtValue_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
+return self._errorNotFound();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"keyAtValue:",{anObject:anObject},smalltalk.HashedCollection)})},
+args: ["anObject"],
+source: "keyAtValue: anObject\x0a\x09^ self keyAtValue: anObject ifAbsent: [ self errorNotFound ]",
+messageSends: ["keyAtValue:ifAbsent:", "errorNotFound"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "keyAtValue:ifAbsent:",
+category: 'accessing',
+fn: function (anObject,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._indexOf_ifAbsent_(anObject,aBlock);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"keyAtValue:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.HashedCollection)})},
+args: ["anObject", "aBlock"],
+source: "keyAtValue: anObject ifAbsent: aBlock\x0a\x09^ self indexOf: anObject ifAbsent: aBlock",
+messageSends: ["indexOf:ifAbsent:"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "keys",
@@ -1534,7 +1573,7 @@ category: 'printing',
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.IndexableCollection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.HashedCollection.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 _st(self._associations())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -1945,7 +1984,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HashedCollection.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Dictionary.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@keys"]=[];
 self["@values"]=[];
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Dictionary)})},
@@ -2850,7 +2889,7 @@ category: 'printing',
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.SequenceableCollection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Array.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 self._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -2899,10 +2938,26 @@ category: 'adding/removing',
 fn: function (aNumber,anotherNumber){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self.splice(aNumber - 1,anotherNumber - 1);
+self.splice(aNumber -1, anotherNumber - aNumber + 1);
 return self}, function($ctx1) {$ctx1.fill(self,"removeFrom:to:",{aNumber:aNumber,anotherNumber:anotherNumber},smalltalk.Array)})},
 args: ["aNumber", "anotherNumber"],
-source: "removeFrom: aNumber to: anotherNumber\x0a\x09<self.splice(aNumber - 1,anotherNumber - 1)>",
+source: "removeFrom: aNumber to: anotherNumber\x0a\x09<self.splice(aNumber -1, anotherNumber - aNumber + 1)>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Array);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "removeIndex:",
+category: 'adding/removing',
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self.splice(anInteger - 1, 1);
+return self}, function($ctx1) {$ctx1.fill(self,"removeIndex:",{anInteger:anInteger},smalltalk.Array)})},
+args: ["anInteger"],
+source: "removeIndex: anInteger\x0a\x09<self.splice(anInteger - 1, 1)>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -3164,7 +3219,7 @@ smalltalk.CharacterArray);
 smalltalk.addMethod(
 smalltalk.method({
 selector: "add:",
-category: 'adding',
+category: 'adding/removing',
 fn: function (anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -4721,7 +4776,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Collection.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Set.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@elements"]=[];
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Set)})},
 args: [],
@@ -4738,7 +4793,7 @@ category: 'printing',
 fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Collection.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Set.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 _st(aStream)._nextPutAll_(" (");
 self._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -4845,7 +4900,7 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Queue.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@read"]=_st($OrderedCollection())._new();
 self["@write"]=_st($OrderedCollection())._new();
 self["@readIndex"]=(1);

+ 5 - 5
js/Kernel-Methods.deploy.js

@@ -670,7 +670,7 @@ fn: function (){
 var self=this;
 function $Queue(){return smalltalk.Queue||(typeof Queue=="undefined"?nil:Queue)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ForkPool.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@poolSize"]=(0);
 self["@queue"]=_st($Queue())._new();
 self["@worker"]=self._makeWorker();
@@ -819,7 +819,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Message.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._selector());
@@ -916,7 +916,7 @@ fn: function (){
 var self=this;
 function $Message(){return smalltalk.Message||(typeof Message=="undefined"?nil:Message)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.MessageSend.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@message"]=_st($Message())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.MessageSend)})},
 messageSends: ["initialize", "new"]}),
@@ -929,7 +929,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.MessageSend.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._receiver());
@@ -1202,7 +1202,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.MethodContext.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._asString());

+ 5 - 5
js/Kernel-Methods.js

@@ -914,7 +914,7 @@ fn: function (){
 var self=this;
 function $Queue(){return smalltalk.Queue||(typeof Queue=="undefined"?nil:Queue)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ForkPool.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@poolSize"]=(0);
 self["@queue"]=_st($Queue())._new();
 self["@worker"]=self._makeWorker();
@@ -1109,7 +1109,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Message.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._selector());
@@ -1242,7 +1242,7 @@ fn: function (){
 var self=this;
 function $Message(){return smalltalk.Message||(typeof Message=="undefined"?nil:Message)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.MessageSend.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@message"]=_st($Message())._new();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.MessageSend)})},
 args: [],
@@ -1260,7 +1260,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.MessageSend.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._receiver());
@@ -1629,7 +1629,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.MethodContext.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_("(");
 _st($1)._nextPutAll_(self._asString());

+ 42 - 7
js/Kernel-Objects.deploy.js

@@ -2184,7 +2184,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self._lookupProperty_(_st(_st(aMessage)._selector())._asJavaScriptSelector());
 if(($receiver = $2) == nil || $receiver == undefined){
-$1=smalltalk.Object.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
+$1=smalltalk.JSObjectProxy.superclass.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
 } else {
 var jsSelector;
 jsSelector=$receiver;
@@ -2296,7 +2296,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 $1=self._at_ifAbsent_("value",(function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.Object.fn.prototype._value.apply(_st(self), []);
+return smalltalk.JSObjectProxy.superclass.fn.prototype._value.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"value",{},smalltalk.JSObjectProxy)})},
@@ -3012,7 +3012,7 @@ function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnno
 function $ProtocolAdded(){return smalltalk.ProtocolAdded||(typeof ProtocolAdded=="undefined"?nil:ProtocolAdded)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Organizer.fn.prototype._addElement_.apply(_st(self), [aString]);
+smalltalk.ClassOrganizer.superclass.fn.prototype._addElement_.apply(_st(self), [aString]);
 $1=_st($ProtocolAdded())._new();
 _st($1)._protocol_(aString);
 _st($1)._theClass_(self._theClass());
@@ -3031,7 +3031,7 @@ function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnno
 function $ProtocolRemoved(){return smalltalk.ProtocolRemoved||(typeof ProtocolRemoved=="undefined"?nil:ProtocolRemoved)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Organizer.fn.prototype._removeElement_.apply(_st(self), [aString]);
+smalltalk.ClassOrganizer.superclass.fn.prototype._removeElement_.apply(_st(self), [aString]);
 $1=_st($ProtocolRemoved())._new();
 _st($1)._protocol_(aString);
 _st($1)._theClass_(self._theClass());
@@ -3182,7 +3182,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Package.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_(" (");
 _st($1)._nextPutAll_(self._name());
@@ -3309,7 +3309,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Package.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._commitPathsFromLoader();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Package.klass)})},
 messageSends: ["initialize", "commitPathsFromLoader"]}),
@@ -3719,6 +3719,17 @@ smalltalk.Random);
 
 
 smalltalk.addClass('Smalltalk', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addGlobalJsVariable:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._globalJsVariables())._add_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"addGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+messageSends: ["add:", "globalJsVariables"]}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asSmalltalkException:",
@@ -3815,6 +3826,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"deleteClass:",{aClass:aClass},sm
 messageSends: []}),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deleteGlobalJsVariable:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._globalJsVariables())._remove_ifAbsent_(aString,(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"deleteGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+messageSends: ["remove:ifAbsent:", "globalJsVariables"]}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "deletePackage:",
@@ -3826,6 +3850,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"deletePackage:",{packageName:pac
 messageSends: []}),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "globalJsVariables",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.globalJsVariables;
+return self}, function($ctx1) {$ctx1.fill(self,"globalJsVariables",{},smalltalk.Smalltalk)})},
+messageSends: []}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isSmalltalkObject:",
@@ -4020,7 +4055,7 @@ selector: "version",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "0.10";
+return "0.11.0";
 }, function($ctx1) {$ctx1.fill(self,"version",{},smalltalk.Smalltalk)})},
 messageSends: []}),
 smalltalk.Smalltalk);

+ 58 - 8
js/Kernel-Objects.js

@@ -3006,7 +3006,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self._lookupProperty_(_st(_st(aMessage)._selector())._asJavaScriptSelector());
 if(($receiver = $2) == nil || $receiver == undefined){
-$1=smalltalk.Object.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
+$1=smalltalk.JSObjectProxy.superclass.fn.prototype._doesNotUnderstand_.apply(_st(self), [aMessage]);
 } else {
 var jsSelector;
 jsSelector=$receiver;
@@ -3158,7 +3158,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 $1=self._at_ifAbsent_("value",(function(){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.Object.fn.prototype._value.apply(_st(self), []);
+return smalltalk.JSObjectProxy.superclass.fn.prototype._value.apply(_st(self), []);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"value",{},smalltalk.JSObjectProxy)})},
@@ -4127,7 +4127,7 @@ function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnno
 function $ProtocolAdded(){return smalltalk.ProtocolAdded||(typeof ProtocolAdded=="undefined"?nil:ProtocolAdded)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Organizer.fn.prototype._addElement_.apply(_st(self), [aString]);
+smalltalk.ClassOrganizer.superclass.fn.prototype._addElement_.apply(_st(self), [aString]);
 $1=_st($ProtocolAdded())._new();
 _st($1)._protocol_(aString);
 _st($1)._theClass_(self._theClass());
@@ -4151,7 +4151,7 @@ function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnno
 function $ProtocolRemoved(){return smalltalk.ProtocolRemoved||(typeof ProtocolRemoved=="undefined"?nil:ProtocolRemoved)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Organizer.fn.prototype._removeElement_.apply(_st(self), [aString]);
+smalltalk.ClassOrganizer.superclass.fn.prototype._removeElement_.apply(_st(self), [aString]);
 $1=_st($ProtocolRemoved())._new();
 _st($1)._protocol_(aString);
 _st($1)._theClass_(self._theClass());
@@ -4359,7 +4359,7 @@ fn: function (aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.Object.fn.prototype._printOn_.apply(_st(self), [aStream]);
+smalltalk.Package.superclass.fn.prototype._printOn_.apply(_st(self), [aStream]);
 $1=aStream;
 _st($1)._nextPutAll_(" (");
 _st($1)._nextPutAll_(self._name());
@@ -4526,7 +4526,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.klass.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.Package.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._commitPathsFromLoader();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Package.klass)})},
 args: [],
@@ -5079,6 +5079,22 @@ smalltalk.Random);
 
 smalltalk.addClass('Smalltalk', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.Smalltalk.comment="I represent the global JavaScript variable `smalltalk` declared in `js/boot.js`.\x0a\x0a## API\x0a\x0aI have only one instance, accessed with class-side method `#current`.\x0a\x0aThe `smalltalk` object holds all class and packages defined in the system.\x0a\x0a## Classes\x0a\x0aClasses can be accessed using the following methods:\x0a\x0a- `#classes` answers the full list of Smalltalk classes in the system\x0a- `#at:` answers a specific class or `nil`\x0a\x0a## Packages\x0a\x0aPackages can be accessed using the following methods:\x0a\x0a- `#packages` answers the full list of packages\x0a- `#packageAt:` answers a specific package or `nil`\x0a\x0a## Parsing\x0a\x0aThe `#parse:` method is used to parse Amber source code.\x0aIt requires the `Compiler` package and the `js/parser.js` parser file in order to work.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addGlobalJsVariable:",
+category: 'globals',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._globalJsVariables())._add_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"addGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+args: ["aString"],
+source: "addGlobalJsVariable: aString\x0a\x09self globalJsVariables add: aString",
+messageSends: ["add:", "globalJsVariables"],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asSmalltalkException:",
@@ -5210,6 +5226,24 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deleteGlobalJsVariable:",
+category: 'globals',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._globalJsVariables())._remove_ifAbsent_(aString,(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"deleteGlobalJsVariable:",{aString:aString},smalltalk.Smalltalk)})},
+args: ["aString"],
+source: "deleteGlobalJsVariable: aString\x0a\x09self globalJsVariables remove: aString ifAbsent:[]",
+messageSends: ["remove:ifAbsent:", "globalJsVariables"],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "deletePackage:",
@@ -5226,6 +5260,22 @@ referencedClasses: []
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "globalJsVariables",
+category: 'globals',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.globalJsVariables;
+return self}, function($ctx1) {$ctx1.fill(self,"globalJsVariables",{},smalltalk.Smalltalk)})},
+args: [],
+source: "globalJsVariables\x0a\x09\x22Array of global JavaScript variables\x22\x0a\x09<return self.globalJsVariables>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isSmalltalkObject:",
@@ -5481,10 +5531,10 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return "0.10";
+return "0.11.0";
 }, function($ctx1) {$ctx1.fill(self,"version",{},smalltalk.Smalltalk)})},
 args: [],
-source: "version\x0a\x09\x22Answer the version string of Amber\x22\x0a\x09\x0a\x09^ '0.10'",
+source: "version\x0a\x09\x22Answer the version string of Amber\x22\x0a\x09\x0a\x09^ '0.11.0'",
 messageSends: [],
 referencedClasses: []
 }),

+ 60 - 1
js/Kernel-Tests.deploy.js

@@ -1672,6 +1672,32 @@ return self}, function($ctx1) {$ctx1.fill(self,"testPrintString",{array:array},s
 messageSends: ["new", "assert:equals:", "printString", "add:", "remove:", "addLast:"]}),
 smalltalk.ArrayTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testRemoveFromTo",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((1),(3)),[(4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((2),(3)),[(1), (4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((2),(4)),[(1)]);
+return self}, function($ctx1) {$ctx1.fill(self,"testRemoveFromTo",{},smalltalk.ArrayTest)})},
+messageSends: ["assert:equals:", "removeFrom:to:"]}),
+smalltalk.ArrayTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testRemoveIndex",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._assert_equals_([(1), (2), (3), (4)]._removeIndex_((2)),[(1), (3), (4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeIndex_((1)),[(2), (3), (4)]);
+self._assert_equals_(["hello"]._removeIndex_((1)),[]);
+return self}, function($ctx1) {$ctx1.fill(self,"testRemoveIndex",{},smalltalk.ArrayTest)})},
+messageSends: ["assert:equals:", "removeIndex:"]}),
+smalltalk.ArrayTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -2769,6 +2795,39 @@ smalltalk.ObjectMock);
 
 
 
+smalltalk.addClass('ObjectMock2', smalltalk.ObjectMock, [], 'Kernel-Tests');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "foo",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@foo"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"foo",{},smalltalk.ObjectMock2)})},
+messageSends: []}),
+smalltalk.ObjectMock2);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "foo:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@foo"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"foo:",{anObject:anObject},smalltalk.ObjectMock2)})},
+messageSends: []}),
+smalltalk.ObjectMock2);
+
+
+
+smalltalk.addClass('ObjectMock3', smalltalk.ObjectMock2, [], 'Kernel-Tests');
+
+
+smalltalk.addClass('ObjectMock4', smalltalk.ObjectMock3, [], 'Kernel-Tests');
+
+
 smalltalk.addClass('ObjectTest', smalltalk.TestCase, [], 'Kernel-Tests');
 smalltalk.addMethod(
 smalltalk.method({
@@ -3085,7 +3144,7 @@ var self=this;
 function $Package(){return smalltalk.Package||(typeof Package=="undefined"?nil:Package)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.PackageTest.fn.prototype._setUp.apply(_st(self), []);
+smalltalk.PackageWithDefaultCommitPathChangedTest.superclass.fn.prototype._setUp.apply(_st(self), []);
 $1=$Package();
 _st($1)._defaultCommitPathJs_("javascripts/");
 $2=_st($1)._defaultCommitPathSt_("smalltalk/");

+ 81 - 1
js/Kernel-Tests.js

@@ -2077,6 +2077,42 @@ referencedClasses: ["Array"]
 }),
 smalltalk.ArrayTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testRemoveFromTo",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((1),(3)),[(4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((2),(3)),[(1), (4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeFrom_to_((2),(4)),[(1)]);
+return self}, function($ctx1) {$ctx1.fill(self,"testRemoveFromTo",{},smalltalk.ArrayTest)})},
+args: [],
+source: "testRemoveFromTo\x0a\x09\x0a\x09self assert: (#(1 2 3 4) removeFrom: 1 to: 3) equals: #(4).\x0a\x09self assert: (#(1 2 3 4) removeFrom: 2 to: 3) equals: #(1 4).\x0a\x09self assert: (#(1 2 3 4) removeFrom: 2 to: 4) equals: #(1)",
+messageSends: ["assert:equals:", "removeFrom:to:"],
+referencedClasses: []
+}),
+smalltalk.ArrayTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testRemoveIndex",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._assert_equals_([(1), (2), (3), (4)]._removeIndex_((2)),[(1), (3), (4)]);
+self._assert_equals_([(1), (2), (3), (4)]._removeIndex_((1)),[(2), (3), (4)]);
+self._assert_equals_(["hello"]._removeIndex_((1)),[]);
+return self}, function($ctx1) {$ctx1.fill(self,"testRemoveIndex",{},smalltalk.ArrayTest)})},
+args: [],
+source: "testRemoveIndex\x0a\x09\x0a\x09self assert: (#(1 2 3 4) removeIndex: 2) equals: #(1 3 4).\x0a\x09self assert: (#(1 2 3 4) removeIndex: 1) equals: #(2 3 4).\x0a\x09self assert: (#('hello') removeIndex: 1) equals: #()",
+messageSends: ["assert:equals:", "removeIndex:"],
+referencedClasses: []
+}),
+smalltalk.ArrayTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -3460,6 +3496,50 @@ smalltalk.ObjectMock);
 
 
 
+smalltalk.addClass('ObjectMock2', smalltalk.ObjectMock, [], 'Kernel-Tests');
+smalltalk.ObjectMock2.comment="ObjectMock is there only to perform tests on classes.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "foo",
+category: 'not yet classified',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@foo"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"foo",{},smalltalk.ObjectMock2)})},
+args: [],
+source: "foo\x0a\x09^foo",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ObjectMock2);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "foo:",
+category: 'not yet classified',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@foo"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"foo:",{anObject:anObject},smalltalk.ObjectMock2)})},
+args: ["anObject"],
+source: "foo: anObject\x0a\x09foo := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ObjectMock2);
+
+
+
+smalltalk.addClass('ObjectMock3', smalltalk.ObjectMock2, [], 'Kernel-Tests');
+
+
+smalltalk.addClass('ObjectMock4', smalltalk.ObjectMock3, [], 'Kernel-Tests');
+
+
 smalltalk.addClass('ObjectTest', smalltalk.TestCase, [], 'Kernel-Tests');
 smalltalk.addMethod(
 smalltalk.method({
@@ -3867,7 +3947,7 @@ var self=this;
 function $Package(){return smalltalk.Package||(typeof Package=="undefined"?nil:Package)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-smalltalk.PackageTest.fn.prototype._setUp.apply(_st(self), []);
+smalltalk.PackageWithDefaultCommitPathChangedTest.superclass.fn.prototype._setUp.apply(_st(self), []);
 $1=$Package();
 _st($1)._defaultCommitPathJs_("javascripts/");
 $2=_st($1)._defaultCommitPathSt_("smalltalk/");

+ 5 - 5
js/SUnit.deploy.js

@@ -514,7 +514,7 @@ _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx3) {
-return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
+return smalltalk.ReportingTestContext.superclass.fn.prototype._execute_.apply(_st(self), [aBlock]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -580,7 +580,7 @@ fn: function (aTestCase,aTestResult,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
-$2=smalltalk.TestContext.klass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
+$2=smalltalk.ReportingTestContext.klass.superclass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
 _st($2)._result_(aTestResult);
 _st($2)._finished_(aBlock);
 $3=_st($2)._yourself();
@@ -662,7 +662,7 @@ var self=this;
 function $Date(){return smalltalk.Date||(typeof Date=="undefined"?nil:Date)}
 function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestResult.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@timestamp"]=_st($Date())._now();
 self["@runs"]=(0);
 self["@errors"]=_st($Array())._new();
@@ -829,7 +829,7 @@ function $Announcer(){return smalltalk.Announcer||(typeof Announcer=="undefined"
 function $TestResult(){return smalltalk.TestResult||(typeof TestResult=="undefined"?nil:TestResult)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestSuiteRunner.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@announcer"]=_st($Announcer())._new();
 self["@result"]=_st($TestResult())._new();
 self["@runNextTest"]=(function(){
@@ -914,7 +914,7 @@ fn: function (aCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
+$1=_st(smalltalk.TestSuiteRunner.klass.superclass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"on:",{aCollection:aCollection},smalltalk.TestSuiteRunner.klass)})},
 messageSends: ["suite:", "new"]}),

+ 5 - 5
js/SUnit.js

@@ -689,7 +689,7 @@ _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._withErrorReporting_((function(){
 return smalltalk.withContext(function($ctx3) {
-return smalltalk.TestContext.fn.prototype._execute_.apply(_st(self), [aBlock]);
+return smalltalk.ReportingTestContext.superclass.fn.prototype._execute_.apply(_st(self), [aBlock]);
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -775,7 +775,7 @@ fn: function (aTestCase,aTestResult,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
-$2=smalltalk.TestContext.klass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
+$2=smalltalk.ReportingTestContext.klass.superclass.fn.prototype._testCase_.apply(_st(self), [aTestCase]);
 _st($2)._result_(aTestResult);
 _st($2)._finished_(aBlock);
 $3=_st($2)._yourself();
@@ -889,7 +889,7 @@ var self=this;
 function $Date(){return smalltalk.Date||(typeof Date=="undefined"?nil:Date)}
 function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestResult.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@timestamp"]=_st($Date())._now();
 self["@runs"]=(0);
 self["@errors"]=_st($Array())._new();
@@ -1107,7 +1107,7 @@ function $Announcer(){return smalltalk.Announcer||(typeof Announcer=="undefined"
 function $TestResult(){return smalltalk.TestResult||(typeof TestResult=="undefined"?nil:TestResult)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.TestSuiteRunner.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@announcer"]=_st($Announcer())._new();
 self["@result"]=_st($TestResult())._new();
 self["@runNextTest"]=(function(){
@@ -1222,7 +1222,7 @@ fn: function (aCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.Object.klass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
+$1=_st(smalltalk.TestSuiteRunner.klass.superclass.fn.prototype._new.apply(_st(self), []))._suite_(aCollection);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"on:",{aCollection:aCollection},smalltalk.TestSuiteRunner.klass)})},
 args: ["aCollection"],

+ 1 - 1
js/Spaces.deploy.js

@@ -83,7 +83,7 @@ selector: "initialize",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ObjectSpace.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._create();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ObjectSpace)})},
 messageSends: ["initialize", "create"]}),

+ 1 - 1
js/Spaces.js

@@ -110,7 +110,7 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+smalltalk.ObjectSpace.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._create();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ObjectSpace)})},
 args: [],

+ 28 - 8
js/boot.js

@@ -128,6 +128,8 @@ function Smalltalk() {
 		'implements', 'interface', 'let', 'package', 'private', 'protected',
 		'public', 'static', 'yield'];
 
+	st.globalJsVariables = ['jQuery', 'window', 'document', 'process', 'global'];
+
 	var initialized = false;
 
 	/* Smalltalk classes */
@@ -156,10 +158,12 @@ function Smalltalk() {
 		/* Dnu handler method */
 
 		createHandler: function (selector) {
-			return function () {
+			var handler = function() {
 				var args = Array.prototype.slice.call(arguments);
 				return messageNotUnderstood(this, selector, args);
 			};
+
+			return handler;
 		}
 	};
 
@@ -273,6 +277,7 @@ function Smalltalk() {
 
 	st.initClass = function(klass) {
 		if(klass.wrapped) {
+			klass.inheritedMethods = {};
 			copySuperclass(klass);
 		} else {
 			installSuperclass(klass);
@@ -306,7 +311,7 @@ function Smalltalk() {
 			superclass && superclass !== nil;
 			superclass = superclass.superclass) {
 			for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
-				installMethodIfAbsent(superclass.methods[keys[i]], klass);
+				inheritMethodIfAbsent(superclass.methods[keys[i]], klass);
 			}
 		}
 	}
@@ -318,10 +323,15 @@ function Smalltalk() {
 		});
 	}
 
-	function installMethodIfAbsent(method, klass) {
-		if(!klass.fn.prototype[method.jsSelector]) {
-			installMethod(method, klass);
+	function inheritMethodIfAbsent(method, klass) {
+		var selector = method.selector;
+
+		if(klass.methods.hasOwnProperty(selector) || klass.inheritedMethods.hasOwnProperty(selector)) {
+			return;
 		}
+
+		installMethod(method, klass);
+		klass.inheritedMethods[method.selector] = true;
 	}
 
 	function reinstallMethods(klass) {
@@ -333,14 +343,21 @@ function Smalltalk() {
 	function installDnuHandlers(klass) {
 		var m = dnu.methods;
 		for(var i=0; i<m.length; i++) {
-			installMethodIfAbsent(m[i], klass);
+			installDnuHandlerIfAbsent(m[i], klass);
 		}
 	}
 
 	function installNewDnuHandler(newHandler) {
-		installMethodIfAbsent(newHandler, st.Object);
+		installDnuHandlerIfAbsent(newHandler, st.Object);
 		for(var i = 0; i < wrappedClasses.length; i++) {
-			installMethodIfAbsent(newHandler, wrappedClasses[i]);
+			installDnuHandlerIfAbsent(newHandler, wrappedClasses[i]);
+		}
+	}
+
+	function installDnuHandlerIfAbsent(handler, klass) {
+		var jsFunction = klass.fn.prototype[handler.jsSelector];
+		if(!jsFunction) {
+			installMethod(handler, klass);
 		}
 	}
 
@@ -533,6 +550,9 @@ function Smalltalk() {
 
 		delete klass.fn.prototype[st.selector(method.selector)];
 		delete klass.methods[method.selector];
+
+		// Do *not* delete protocols from here.
+		// This is handled by #removeCompiledMethod
 	};
 
 	/* Handles unhandled errors during message sends */

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
     "name": "amber",
-    "version": "0.10.0",
+    "version": "0.11.0",
     "description": "An implementation of the Smalltalk language that runs on top of the JS runtime.",
     "homepage": "http://amber-lang.net",
     "keywords": [ "javascript", "smalltalk", "language", "compiler", "web" ],
@@ -14,7 +14,7 @@
     },
     "repository": {
         "type": "git",
-        "url": "git://github.com/amber-smalltalk/amber.git#0.10.0"
+        "url": "git://github.com/amber-smalltalk/amber.git#0.11.0"
     },
     "engines": {
         "node": "0.8.x"

+ 1 - 0
st/Compiler-Core.st

@@ -62,6 +62,7 @@ compileNode: aNode
 	self semanticAnalyzer visit: aNode.
 	ir := self translator visit: aNode.
 	^ self irTranslator
+		currentClass: self currentClass;
 		visit: ir;
 		contents
 !

+ 11 - 2
st/Compiler-IR.st

@@ -868,7 +868,7 @@ visitIRVerbatim: anIRVerbatim
 ! !
 
 IRVisitor subclass: #IRJSTranslator
-	instanceVariableNames: 'stream'
+	instanceVariableNames: 'stream currentClass'
 	package: 'Compiler-IR'!
 
 !IRJSTranslator methodsFor: 'accessing'!
@@ -877,6 +877,14 @@ contents
 	^ self stream contents
 !
 
+currentClass
+	^ currentClass
+!
+
+currentClass: aClass
+	currentClass := aClass
+!
+
 stream
 	^ stream
 !
@@ -1010,7 +1018,8 @@ visitSend: anIRSend
 
 visitSuperSend: anIRSend
 	self stream
-		nextPutAll: anIRSend classSend asJavascript, '.fn.prototype.';
+		nextPutAll: self currentClass asJavascript;
+		nextPutAll: '.superclass.fn.prototype.';
 		nextPutAll: anIRSend selector asSelector, '.apply(';
 		nextPutAll: '_st('.
 	self visit: anIRSend instructions first.

+ 1 - 0
st/Compiler-Inlining.st

@@ -597,6 +597,7 @@ compileNode: aNode
 	self inliner visit: ir.
 
 	^ self irTranslator
+		currentClass: self currentClass;
 		visit: ir;
 		contents
 !

+ 7 - 7
st/Compiler-Interpreter.st

@@ -973,11 +973,11 @@ peek
 pop
 	"Pop an object from the context stack"
 	
-	| value |
+	| peekedValue |
 	
-	value := self peek.
+	peekedValue := self peek.
 	self stack removeLast.
-	^ value
+	^ peekedValue
 !
 
 push: anObject
@@ -1003,16 +1003,16 @@ visit: aNode
 !
 
 visitAssignmentNode: aNode
-	| value |
+	| poppedValue |
 	
-	value := self pop.
+	poppedValue := self pop.
 	
 	"Pop the left side of the assignment.
 	It already has been visited, and we don't need its value."
 	self pop.
 	
-	self push: value.
-	self assign: aNode left to: value
+	self push: poppedValue.
+	self assign: aNode left to: poppedValue
 !
 
 visitBlockNode: aNode

+ 3 - 2
st/Compiler-Semantic.st

@@ -425,7 +425,8 @@ errorShadowingVariable: aString
 
 errorUnknownVariable: aNode
 	"Throw an error if the variable is undeclared in the global JS scope (i.e. window).
-	We allow four variable names in addition: `jQuery`, `window`, `process` and `global`
+	We allow all variables listed by Smalltalk>>#globalJsVariables.
+	This list includes: `jQuery`, `window`, `document`,  `process` and `global`
 	for nodejs and browser environments.
 	
 	This is only to make sure compilation works on both browser-based and nodejs environments.
@@ -434,7 +435,7 @@ errorUnknownVariable: aNode
 	| identifier |
 	identifier := aNode value.
 	
-	((#('jQuery' 'window' 'document' 'process' 'global') includes: identifier) not
+	((Smalltalk current globalJsVariables includes: identifier) not
 		and: [ self isVariableGloballyUndefined: identifier ])
 			ifTrue: [
 				UnknownVariableError new

+ 1 - 3
st/Helios-Inspector.st

@@ -312,9 +312,7 @@ observeVariablesWidget
 !
 
 refresh
-	self 
-		refreshVariablesWidget;
-		refreshDisplayWidget
+	self inspect: self inspectee
 !
 
 refreshDisplayWidget

+ 7 - 0
st/Kernel-Classes.st

@@ -210,6 +210,10 @@ compile: aString category: anotherString
 		category: anotherString
 !
 
+recompile
+	^ Compiler new recompile: self
+!
+
 removeCompiledMethod: aMethod
 	self basicRemoveCompiledMethod: aMethod.
 	
@@ -573,6 +577,9 @@ migrateClassNamed: className superclass: aClass instanceVariableNames: aCollecti
 renameClass: aClass to: className
 	self basicRenameClass: aClass to: className.
 	
+	"Recompile the class to fix potential issues with super sends"
+	aClass recompile.
+	
 	SystemAnnouncer current
 		announce: (ClassRenamed new
 			theClass: aClass;

+ 18 - 4
st/Kernel-Collections.st

@@ -416,6 +416,14 @@ indexOf: anObject ifAbsent: aBlock
 	^ self keys detect: [ :each | (self at: each) = anObject ] ifNone: aBlock
 !
 
+keyAtValue: anObject
+	^ self keyAtValue: anObject ifAbsent: [ self errorNotFound ]
+!
+
+keyAtValue: anObject ifAbsent: aBlock
+	^ self indexOf: anObject ifAbsent: aBlock
+!
+
 keys
 	<
 		if ('function'===typeof Object.keys) return Object.keys(self);
@@ -976,7 +984,11 @@ remove: anObject ifAbsent: aBlock
 !
 
 removeFrom: aNumber to: anotherNumber
-	<self.splice(aNumber - 1,anotherNumber - 1)>
+	<self.splice(aNumber -1, anotherNumber - aNumber + 1)>
+!
+
+removeIndex: anInteger
+	<self.splice(anInteger - 1, 1)>
 !
 
 removeLast
@@ -1082,11 +1094,13 @@ at: anIndex put: anObject
 
 !CharacterArray methodsFor: 'adding'!
 
-add: anObject
+remove: anObject ifAbsent: aBlock
 	self errorReadOnly
-!
+! !
 
-remove: anObject ifAbsent: aBlock
+!CharacterArray methodsFor: 'adding/removing'!
+
+add: anObject
 	self errorReadOnly
 ! !
 

+ 16 - 1
st/Kernel-Objects.st

@@ -1834,7 +1834,7 @@ reservedWords
 version
 	"Answer the version string of Amber"
 	
-	^ '0.10'
+	^ '0.11.0'
 ! !
 
 !Smalltalk methodsFor: 'classes'!
@@ -1875,6 +1875,21 @@ parseError: anException parsing: aString
 	^ ParseError new messageText: 'Parse error on line ', (anException basicAt: 'line') ,' column ' , (anException basicAt: 'column') ,' : Unexpected character ', (anException basicAt: 'found')
 ! !
 
+!Smalltalk methodsFor: 'globals'!
+
+addGlobalJsVariable: aString
+	self globalJsVariables add: aString
+!
+
+deleteGlobalJsVariable: aString
+	self globalJsVariables remove: aString ifAbsent:[]
+!
+
+globalJsVariables
+	"Array of global JavaScript variables"
+	<return self.globalJsVariables>
+! !
+
 !Smalltalk methodsFor: 'packages'!
 
 createPackage: packageName

+ 38 - 0
st/Kernel-Tests.st

@@ -797,6 +797,20 @@ testPrintString
 	self assert: array printString equals: 'an Array (''foo'' 3)'.
 	array addLast: 3.
 	self assert: array printString equals: 'an Array (''foo'' 3 3)'.
+!
+
+testRemoveFromTo
+	
+	self assert: (#(1 2 3 4) removeFrom: 1 to: 3) equals: #(4).
+	self assert: (#(1 2 3 4) removeFrom: 2 to: 3) equals: #(1 4).
+	self assert: (#(1 2 3 4) removeFrom: 2 to: 4) equals: #(1)
+!
+
+testRemoveIndex
+	
+	self assert: (#(1 2 3 4) removeIndex: 2) equals: #(1 3 4).
+	self assert: (#(1 2 3 4) removeIndex: 1) equals: #(2 3 4).
+	self assert: (#('hello') removeIndex: 1) equals: #()
 ! !
 
 !ArrayTest class methodsFor: 'accessing'!
@@ -1315,6 +1329,30 @@ foo: anObject
 	foo := anObject
 ! !
 
+ObjectMock subclass: #ObjectMock2
+	instanceVariableNames: ''
+	package: 'Kernel-Tests'!
+!ObjectMock2 commentStamp!
+ObjectMock is there only to perform tests on classes.!
+
+!ObjectMock2 methodsFor: 'not yet classified'!
+
+foo
+	^foo
+!
+
+foo: anObject
+	foo := anObject
+! !
+
+ObjectMock2 subclass: #ObjectMock3
+	instanceVariableNames: ''
+	package: 'Kernel-Tests'!
+
+ObjectMock3 subclass: #ObjectMock4
+	instanceVariableNames: ''
+	package: 'Kernel-Tests'!
+
 TestCase subclass: #ObjectTest
 	instanceVariableNames: ''
 	package: 'Kernel-Tests'!