1
0
Bläddra i källkod

Merge branch 'master' of github.com:amber-smalltalk/amber

Nicolas Petton 10 år sedan
förälder
incheckning
7567c90ad8

+ 5 - 5
CHANGELOG

@@ -1,13 +1,13 @@
-??th ??? 20?? - Release 0.12.3
+22nd Jan 2014 - Release 0.12.3
 ===================================
 
 Highlights:
 
 * JQuery updated to ~1.10.2; jquery-ui updated to match
-* You can create subclasses of `nil`
-* Amber loads in IE8
-* You can load amber.js asynchronously (it must
-  have id 'amber-path-mapper' in that case)
+* Subclasses of `nil` can be created
+* Several fixes for IE8
+* amber.js can be loaded asynchronously (it must
+  have an id 'amber-path-mapper' in that case)
 * CodeMirror updated to ~3.20.0
 
 Commits: https://github.com/amber-smalltalk/amber/compare/0.12.2...0.12.3

+ 5 - 1
README.md

@@ -26,8 +26,12 @@ Amber is shipped as a [npm](http://npmjs.org) package for its CLI tools and as a
     # Install the CLI tool `amber`
     npm install -g amber
     
+    # Initialize your project as bower package
+    cd /path/to/myproject
+    bower init
+
     # Load amber via bower in your project
-    bower install amber
+    bower install amber --save
     
     # Serve amber on localhost:4000
     amber serve

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 99 - 880
cli/js/AmberCli.js


+ 17 - 5
cli/st/AmberCli.st

@@ -250,12 +250,14 @@ writeData: data toFileNamed: aFilename
 
 handleGETRequest: aRequest respondTo: aResponse
 	| uri filename |
-	uri := (url parse: aRequest url) pathname.
-	filename := path join: self basePath with: uri.
+	uri := url parse: aRequest url.
+	filename := path join: self basePath with: uri pathname.
 	fs exists: filename do: [:aBoolean |
 		aBoolean
 			ifFalse: [self respondNotFoundTo: aResponse]
-			ifTrue: [self respondFileNamed: filename to: aResponse]]
+			ifTrue: [(fs statSync: filename) isDirectory
+				ifTrue: [self respondDirectoryNamed: filename from: uri to: aResponse]
+				ifFalse: [self respondFileNamed: filename to: aResponse]]]
 !
 
 handleOPTIONSRequest: aRequest respondTo: aResponse
@@ -314,12 +316,16 @@ respondCreatedTo: aResponse
 		end.
 !
 
+respondDirectoryNamed: aDirname from: aUrl to: aResponse
+	(aUrl pathname endsWith: '/')
+		ifTrue: [self respondFileNamed: aDirname, 'index.html' to: aResponse]
+		ifFalse: [self respondRedirect: aUrl pathname, '/', (aUrl search ifNil: ['']) to: aResponse]
+!
+
 respondFileNamed: aFilename to: aResponse
 	| type filename |
 
 	filename := aFilename.
-	(fs statSync: aFilename) isDirectory ifTrue: [
-		filename := filename, 'index.html'].
 
 	fs readFile: filename do: [:ex :file |
 		ex notNil 
@@ -367,6 +373,12 @@ respondOKTo: aResponse
 	aResponse
 		writeHead: 200 options: #{'Content-Type' -> 'text/plain'. 'Access-Control-Allow-Origin' -> '*'};
 		end.
+!
+
+respondRedirect: aString to: aResponse
+	aResponse
+		writeHead: 303 options: #{'Location' -> aString};
+		end.
 ! !
 
 !FileServer methodsFor: 'starting'!

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 167 - 93
cli/support/amber-cli.js


+ 9 - 9
cli/support/amberc.js

@@ -43,8 +43,8 @@ function createConcatenator () {
 		},
 		finish: function (realWork) {
 			this.add(
-				'define("amber_vm/_init", ["amber_vm/smalltalk", "amber_vm/globals", "' + this.ids.join('","') + '"], function (smalltalk, globals) {',
-				'smalltalk.initialize();',
+				'define("amber_vm/_init", ["amber_vm/smalltalk", "amber_vm/globals", "' + this.ids.join('","') + '"], function (vm, globals) {',
+				'vm.initialize();',
 				realWork,
 				'});',
 				'requirejs("amber_vm/_init");'
@@ -128,7 +128,7 @@ AmberCompiler.prototype.main = function(configuration, finished_callback) {
 	}
 
 	// the evaluated compiler will be stored in this variable (see create_compiler)
-	configuration.smalltalk = {};
+	configuration.vm = {};
 	configuration.globals = {};
 	configuration.kernel_libraries = this.kernel_libraries;
 	configuration.compiler_libraries = this.compiler_libraries;
@@ -280,7 +280,7 @@ function resolve_kernel(configuration) {
 	)
 	.then(function(data) {
 		// boot.js and Kernel files need to be used first
-		// otherwise the global smalltalk object is undefined
+		// otherwise the global objects 'vm' and 'globals' are undefined
 		configuration.libraries = data.concat(configuration.libraries);
 		return configuration;
 	});
@@ -289,7 +289,7 @@ function resolve_kernel(configuration) {
 
 /**
  * Resolve .js files needed by compiler, read and eval() them.
- * The finished Compiler gets stored in configuration.smalltalk.
+ * The finished Compiler gets stored in configuration.{vm,globals}.
  * Returns a Promise object which resolves into the configuration object.
  */
 function create_compiler(configuration) {
@@ -328,8 +328,8 @@ function create_compiler(configuration) {
 				builder.addId(match[1]);
 			}
 		});
-		// store the generated smalltalk env in configuration.smalltalk
-		builder.finish('configuration.smalltalk = smalltalk; configuration.globals = globals;');
+		// store the generated smalltalk env in configuration.{vm,globals}
+		builder.finish('configuration.vm = vm; configuration.globals = globals;');
 		builder.add('})();');
 
 		eval(builder.toString());
@@ -339,7 +339,7 @@ function create_compiler(configuration) {
 		configuration.globals.ErrorHandler._register_(configuration.globals.RethrowErrorHandler._new());
 
 		if(0 !== configuration.jsGlobals.length) {
-			var jsGlobalVariables = configuration.smalltalk.globalJsVariables;
+			var jsGlobalVariables = configuration.vm.globalJsVariables;
 			jsGlobalVariables.push.apply(jsGlobalVariables, configuration.jsGlobals);
 		}
 
@@ -529,7 +529,7 @@ function compose_js_files(configuration) {
 
 		if (undefined !== configuration.mainfile && fs.existsSync(configuration.mainfile)) {
 			console.log('Adding main file: ' + configuration.mainfile);
-			mainFunctionOrFile += '\n' + fs.readFileSync(configuration.mainfile);
+			mainFunctionOrFile += '\nvar smalltalk = vm; // backward compatibility\n' + fs.readFileSync(configuration.mainfile);
 		}
 
 		builder.finish(mainFunctionOrFile);

+ 51 - 1
js/Canvas.js

@@ -2334,7 +2334,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@snippets"];
 if(($receiver = $2) == nil || $receiver == null){
-self["@snippets"]=globals.HashedCollection._from_([]);
+self["@snippets"]=globals.HashedCollection._newFromPairs_([]);
 $1=self["@snippets"];
 } else {
 $1=$2;
@@ -2672,6 +2672,24 @@ referencedClasses: []
 }),
 globals.TagBrush);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "asJQueryInContext:",
+protocol: 'converting',
+fn: function (aContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._element())._asJQueryInContext_(aContext);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"asJQueryInContext:",{aContext:aContext},globals.TagBrush)})},
+args: ["aContext"],
+source: "asJQueryInContext: aContext\x0a\x09^ self element asJQueryInContext: aContext",
+messageSends: ["asJQueryInContext:", "element"],
+referencedClasses: []
+}),
+globals.TagBrush);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "at:",
@@ -3788,6 +3806,22 @@ referencedClasses: []
 }),
 globals.JSObjectProxy);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "asJQueryInContext:",
+protocol: '*Canvas',
+fn: function (aContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return jQuery(self['@jsObject'], aContext);
+return self}, function($ctx1) {$ctx1.fill(self,"asJQueryInContext:",{aContext:aContext},globals.JSObjectProxy)})},
+args: ["aContext"],
+source: "asJQueryInContext: aContext\x0a\x09<return jQuery(self['@jsObject'], aContext)>",
+messageSends: [],
+referencedClasses: []
+}),
+globals.JSObjectProxy);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "appendToBrush:",
@@ -3868,4 +3902,20 @@ referencedClasses: []
 }),
 globals.String);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "asJQueryInContext:",
+protocol: '*Canvas',
+fn: function (aContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return jQuery(String(self), aContext);
+return self}, function($ctx1) {$ctx1.fill(self,"asJQueryInContext:",{aContext:aContext},globals.String)})},
+args: ["aContext"],
+source: "asJQueryInContext: aContext\x0a\x09<return jQuery(String(self), aContext)>",
+messageSends: [],
+referencedClasses: []
+}),
+globals.String);
+
 });

+ 2 - 2
js/Compiler-IR.js

@@ -2991,7 +2991,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2;
 $1=self._stream();
 $ctx1.sendIdx["stream"]=1;
-_st($1)._nextPutAll_("globals.HashedCollection._from_([");
+_st($1)._nextPutAll_("globals.HashedCollection._newFromPairs_([");
 $ctx1.sendIdx["nextPutAll:"]=1;
 _st(_st(anIRDynamicDictionary)._instructions())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -3006,7 +3006,7 @@ $ctx2.sendIdx["nextPutAll:"]=2;
 _st(self._stream())._nextPutAll_("])");
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRDynamicDictionary:",{anIRDynamicDictionary:anIRDynamicDictionary},globals.IRJSTranslator)})},
 args: ["anIRDynamicDictionary"],
-source: "visitIRDynamicDictionary: anIRDynamicDictionary\x0a\x09self stream nextPutAll: 'globals.HashedCollection._from_(['.\x0a\x09\x09anIRDynamicDictionary instructions\x0a\x09\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
+source: "visitIRDynamicDictionary: anIRDynamicDictionary\x0a\x09self stream nextPutAll: 'globals.HashedCollection._newFromPairs_(['.\x0a\x09\x09anIRDynamicDictionary instructions\x0a\x09\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09\x09separatedBy: [ self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
 messageSends: ["nextPutAll:", "stream", "do:separatedBy:", "instructions", "visit:"],
 referencedClasses: []
 }),

+ 7 - 15
js/Compiler-Interpreter.js

@@ -1819,28 +1819,20 @@ selector: "visitDynamicDictionaryNode:",
 protocol: 'visiting',
 fn: function (aNode){
 var self=this;
-var associations,hashedCollection;
+var keyValueList;
 function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-associations=_st($OrderedCollection())._new();
-$ctx1.sendIdx["new"]=1;
-hashedCollection=_st($HashedCollection())._new();
+keyValueList=_st($OrderedCollection())._new();
 _st(_st(aNode)._nodes())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(associations)._add_(self._pop());
-$ctx2.sendIdx["add:"]=1;
+return _st(keyValueList)._add_(self._pop());
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
-_st(_st(associations)._reversed())._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(hashedCollection)._add_(each);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
-self._push_(hashedCollection);
-return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode,associations:associations,hashedCollection:hashedCollection},globals.ASTInterpreter)})},
+self._push_(_st($HashedCollection())._newFromPairs_(_st(keyValueList)._reversed()));
+return self}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode,keyValueList:keyValueList},globals.ASTInterpreter)})},
 args: ["aNode"],
-source: "visitDynamicDictionaryNode: aNode\x0a\x09| associations hashedCollection |\x0a\x09\x0a\x09associations := OrderedCollection new.\x0a\x09hashedCollection := HashedCollection new.\x0a\x09\x0a\x09aNode nodes do: [ :each | \x0a\x09\x09associations add: self pop ].\x0a\x09\x0a\x09associations reversed do: [ :each |\x0a\x09\x09hashedCollection add: each ].\x0a\x09\x0a\x09self push: hashedCollection",
-messageSends: ["new", "do:", "nodes", "add:", "pop", "reversed", "push:"],
+source: "visitDynamicDictionaryNode: aNode\x0a\x09| keyValueList |\x0a\x09\x0a\x09keyValueList := OrderedCollection new.\x0a\x09\x0a\x09aNode nodes do: [ :each | \x0a\x09\x09keyValueList add: self pop ].\x0a\x09\x0a\x09self push: (HashedCollection newFromPairs: keyValueList reversed)",
+messageSends: ["new", "do:", "nodes", "add:", "pop", "push:", "newFromPairs:", "reversed"],
 referencedClasses: ["OrderedCollection", "HashedCollection"]
 }),
 globals.ASTInterpreter);

+ 30 - 22
js/Compiler-Tests.js

@@ -499,19 +499,36 @@ protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2="foo".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$1=globals.HashedCollection._from_([$2,"bar".__minus_gt((2))]);
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'->1.\x0a\x09^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",$1);
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'.\x0a\x09^ #{ x->1. 'bar'->(true ifTrue: [ 2 ]) }\x0a",globals.HashedCollection._newFromPairs_(["foo",(1),"bar",(2)]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryElementsOrdered",{},globals.CodeGeneratorTest)})},
 args: [],
-source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := ''foo''->1.\x0a\x09^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
-messageSends: ["should:return:", "->"],
+source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := ''foo''.\x0a\x09^ #{ x->1. ''bar''->(true ifTrue: [ 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
+messageSends: ["should:return:"],
 referencedClasses: []
 }),
 globals.CodeGeneratorTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testDynamicDictionaryWithMoreArrows",
+protocol: 'tests',
+fn: function (){
+var self=this;
+function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st((1).__minus_gt((2))).__minus_gt((3));
+$ctx1.sendIdx["->"]=1;
+$1=_st($HashedCollection())._with_($2);
+self._should_return_("foo ^ #{1->2->3}",$1);
+return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryWithMoreArrows",{},globals.CodeGeneratorTest)})},
+args: [],
+source: "testDynamicDictionaryWithMoreArrows\x0a\x09self should: 'foo ^ #{1->2->3}' return: (HashedCollection with: 1->2->3)",
+messageSends: ["should:return:", "with:", "->"],
+referencedClasses: ["HashedCollection"]
+}),
+globals.CodeGeneratorTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testGlobalVar",
@@ -541,7 +558,7 @@ fn: function (){
 var self=this;
 function $Array(){return globals.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$1,$5,$6,$4,$8,$9,$7,$11,$12,$10,$14,$13;
+var $2,$3,$1,$5,$6,$4,$8,$9,$7,$11,$10;
 $2="foo".__minus_gt($Array());
 $ctx1.sendIdx["->"]=1;
 $3="bar".__minus_gt((2));
@@ -565,15 +582,10 @@ self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ Array with: 'foo'
 $ctx1.sendIdx["should:return:"]=3;
 $11="foo".__minus_gt((1));
 $ctx1.sendIdx["->"]=7;
-$12="bar".__minus_gt((2));
-$ctx1.sendIdx["->"]=8;
-$10=[$11,$12];
+$10=[$11,"bar".__minus_gt((2))];
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ { 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",$10);
 $ctx1.sendIdx["should:return:"]=4;
-$14="foo".__minus_gt((1));
-$ctx1.sendIdx["->"]=9;
-$13=globals.HashedCollection._from_([$14,"bar".__minus_gt((2))]);
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",$13);
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",globals.HashedCollection._newFromPairs_(["foo",(1),"bar",(2)]));
 return self}, function($ctx1) {$ctx1.fill(self,"testInnerTemporalDependentElementsOrdered",{},globals.CodeGeneratorTest)})},
 args: [],
 source: "testInnerTemporalDependentElementsOrdered\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := Array.\x0a\x09^ x with: ''foo''->x with: ''bar''->(x := 2)\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := Array.\x0a\x09^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
@@ -605,7 +617,6 @@ protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
 self._should_return_("foo ^ 1",(1));
 $ctx1.sendIdx["should:return:"]=1;
 self._should_return_("foo ^ 'hello'","hello");
@@ -618,10 +629,7 @@ self._should_return_("foo ^ true",true);
 $ctx1.sendIdx["should:return:"]=5;
 self._should_return_("foo ^ false",false);
 $ctx1.sendIdx["should:return:"]=6;
-$2=(1).__minus_gt((2));
-$ctx1.sendIdx["->"]=1;
-$1=globals.HashedCollection._from_([$2,(3).__minus_gt((4))]);
-self._should_return_("foo ^ #{1->2. 3->4}",$1);
+self._should_return_("foo ^ #{1->2. 3->4}",globals.HashedCollection._newFromPairs_([(1),(2),(3),(4)]));
 $ctx1.sendIdx["should:return:"]=7;
 self._should_return_("foo ^ #hello","hello");
 $ctx1.sendIdx["should:return:"]=8;
@@ -631,7 +639,7 @@ self._should_return_("foo ^ -2.5e4",(-25000));
 return self}, function($ctx1) {$ctx1.fill(self,"testLiterals",{},globals.CodeGeneratorTest)})},
 args: [],
 source: "testLiterals\x0a\x09self should: 'foo ^ 1' return: 1.\x0a\x09self should: 'foo ^ ''hello''' return: 'hello'.\x0a\x09self should: 'foo ^ #(1 2 3 4)' return: #(1 2 3 4).\x0a\x09self should: 'foo ^ {1. [:x | x ] value: 2. 3. [4] value}' return: #(1 2 3 4).\x0a\x09self should: 'foo ^ true' return: true.\x0a\x09self should: 'foo ^ false' return: false.\x0a\x09self should: 'foo ^ #{1->2. 3->4}' return: #{1->2. 3->4}.\x0a\x09self should: 'foo ^ #hello' return: #hello.\x0a\x09self should: 'foo ^ -123.456' return: -123.456.\x0a\x09self should: 'foo ^ -2.5e4' return: -25000.",
-messageSends: ["should:return:", "->"],
+messageSends: ["should:return:"],
 referencedClasses: []
 }),
 globals.CodeGeneratorTest);
@@ -1176,7 +1184,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 self["@receiver"]=anObject;
-$1=self._assert_equals_(self._interpret_receiver_withArguments_(aString,self["@receiver"],globals.HashedCollection._from_([])),aResult);
+$1=self._assert_equals_(self._interpret_receiver_withArguments_(aString,self["@receiver"],globals.HashedCollection._newFromPairs_([])),aResult);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"should:receiver:return:",{aString:aString,anObject:anObject,aResult:aResult},globals.InterpreterTest)})},
 args: ["aString", "anObject", "aResult"],

+ 13 - 19
js/Helios-Debugger.js

@@ -558,7 +558,7 @@ fn: function (aNode){
 var self=this;
 var token;
 return smalltalk.withContext(function($ctx1) { 
-var $4,$3,$2,$1,$5,$10,$9,$8,$7,$13,$12,$11,$6,$18,$17,$16,$15,$14;
+var $4,$3,$2,$1,$5,$9,$8,$7,$11,$10,$6,$15,$14,$13,$12;
 if(($receiver = aNode) == nil || $receiver == null){
 aNode;
 } else {
@@ -572,34 +572,28 @@ $ctx1.sendIdx["-"]=1;
 $1=self._addStopAt_($2);
 $1;
 $5=self._editor();
-$10=_st(aNode)._positionStart();
+$9=_st(aNode)._positionStart();
 $ctx1.sendIdx["positionStart"]=2;
-$9=_st($10)._x();
+$8=_st($9)._x();
 $ctx1.sendIdx["x"]=2;
-$8=_st($9).__minus((1));
+$7=_st($8).__minus((1));
 $ctx1.sendIdx["-"]=2;
-$7="line".__minus_gt($8);
-$ctx1.sendIdx["->"]=1;
-$13=_st(_st(aNode)._positionStart())._y();
+$11=_st(_st(aNode)._positionStart())._y();
 $ctx1.sendIdx["y"]=1;
-$12=_st($13).__minus((1));
+$10=_st($11).__minus((1));
 $ctx1.sendIdx["-"]=3;
-$11="ch".__minus_gt($12);
-$ctx1.sendIdx["->"]=2;
-$6=globals.HashedCollection._from_([$7,$11]);
-$18=_st(aNode)._positionEnd();
+$6=globals.HashedCollection._newFromPairs_(["line",$7,"ch",$10]);
+$15=_st(aNode)._positionEnd();
 $ctx1.sendIdx["positionEnd"]=1;
-$17=_st($18)._x();
-$16=_st($17).__minus((1));
-$15="line".__minus_gt($16);
-$ctx1.sendIdx["->"]=3;
-$14=globals.HashedCollection._from_([$15,"ch".__minus_gt(_st(_st(aNode)._positionEnd())._y())]);
-_st($5)._setSelection_to_($6,$14);
+$14=_st($15)._x();
+$13=_st($14).__minus((1));
+$12=globals.HashedCollection._newFromPairs_(["line",$13,"ch",_st(_st(aNode)._positionEnd())._y()]);
+_st($5)._setSelection_to_($6,$12);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"highlightNode:",{aNode:aNode,token:token},globals.HLDebuggerCodeWidget)})},
 args: ["aNode"],
 source: "highlightNode: aNode\x0a\x09| token |\x0a\x09\x0a\x09aNode ifNotNil: [\x0a\x09\x09self\x0a\x09\x09\x09clearHighlight;\x0a\x09\x09\x09addStopAt: aNode positionStart x - 1.\x0a\x0a\x09\x09self editor \x0a\x09\x09\x09setSelection: #{ 'line' -> (aNode positionStart x - 1). 'ch' -> (aNode positionStart y - 1) }\x0a\x09\x09\x09to: #{ 'line' -> (aNode positionEnd x - 1). 'ch' -> (aNode positionEnd y) } ]",
-messageSends: ["ifNotNil:", "clearHighlight", "addStopAt:", "-", "x", "positionStart", "setSelection:to:", "editor", "->", "y", "positionEnd"],
+messageSends: ["ifNotNil:", "clearHighlight", "addStopAt:", "-", "x", "positionStart", "setSelection:to:", "editor", "y", "positionEnd"],
 referencedClasses: []
 }),
 globals.HLDebuggerCodeWidget);

+ 2 - 2
js/Helios-KeyBindings.js

@@ -987,7 +987,7 @@ self["@input"]=$5;
 self["@input"];
 $11=_st(self["@input"])._asJQuery();
 $ctx2.sendIdx["asJQuery"]=2;
-_st($11)._typeahead_(globals.HashedCollection._from_(["source".__minus_gt(self._inputCompletion())]));
+_st($11)._typeahead_(globals.HashedCollection._newFromPairs_(["source",self._inputCompletion()]));
 $12=_st(html)._span();
 _st($12)._class_("help-inline");
 _st($12)._with_(self._message());
@@ -1003,7 +1003,7 @@ return _st(_st(self["@input"])._asJQuery())._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},globals.HLBindingActionInputWidget)})},
 args: ["html"],
 source: "renderOn: html\x0a\x09wrapper ifNil: [ wrapper := html span ].\x0a\x0a\x09wrapper \x0a\x09\x09class: self status;\x0a\x09\x09with: [\x0a\x09\x09\x09input := html input\x0a\x09\x09\x09\x09placeholder: self ghostText;\x0a\x09\x09\x09\x09value: self defaultValue;\x0a\x09\x09\x09\x09onKeyDown: [ :event | \x0a\x09\x09\x09\x09\x09event which = 13 ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self evaluate: input asJQuery val ] ]\x0a\x09\x09\x09\x09yourself.\x0a\x09\x09\x09input asJQuery \x0a\x09\x09\x09\x09typeahead: #{ 'source' -> self inputCompletion }.\x0a\x09\x09\x09messageTag := (html span\x0a\x09\x09\x09\x09class: 'help-inline';\x0a\x09\x09\x09\x09with: self message;\x0a\x09\x09\x09\x09yourself) ].\x0a\x09\x0a\x09\x22Evaluate with a timeout to ensure focus.\x0a\x09Commands can be executed from a menu, clicking on the menu to\x0a\x09evaluate the command would give it the focus otherwise\x22\x0a\x09\x0a\x09[ input asJQuery focus ] valueWithTimeout: 10",
-messageSends: ["ifNil:", "span", "class:", "status", "with:", "placeholder:", "input", "ghostText", "value:", "defaultValue", "onKeyDown:", "yourself", "ifTrue:", "=", "which", "evaluate:", "val", "asJQuery", "typeahead:", "->", "inputCompletion", "message", "valueWithTimeout:", "focus"],
+messageSends: ["ifNil:", "span", "class:", "status", "with:", "placeholder:", "input", "ghostText", "value:", "defaultValue", "onKeyDown:", "yourself", "ifTrue:", "=", "which", "evaluate:", "val", "asJQuery", "typeahead:", "inputCompletion", "message", "valueWithTimeout:", "focus"],
 referencedClasses: []
 }),
 globals.HLBindingActionInputWidget);

+ 10 - 28
js/Helios-Layout.js

@@ -394,29 +394,20 @@ protocol: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$4,$5,$6,$2;
+var $1;
 $1=_st(self["@splitter"])._asJQuery();
 $ctx1.sendIdx["asJQuery"]=1;
-$3="axis".__minus_gt("y");
-$ctx1.sendIdx["->"]=1;
-$4="containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent());
-$ctx1.sendIdx["->"]=2;
-$5="helper".__minus_gt("clone");
-$ctx1.sendIdx["->"]=3;
-$6="start".__minus_gt((function(e,ui){
+_st($1)._draggable_(globals.HashedCollection._newFromPairs_(["axis","y","containment",_st(_st(self["@splitter"])._asJQuery())._parent(),"helper","clone","start",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}));
-$ctx1.sendIdx["->"]=4;
-$2=globals.HashedCollection._from_([$3,$4,$5,$6,"drag".__minus_gt((function(e,ui){
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}),"drag",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._resize_(_st(_st(ui)._offset())._top());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})}))]);
-_st($1)._draggable_($2);
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})})]));
 return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},globals.HLHorizontalSplitter)})},
 args: [],
 source: "setupSplitter\x0a\x09splitter asJQuery draggable: #{ \x0a    \x09'axis' -> 'y'. \x0a        'containment' -> splitter asJQuery parent.\x0a        'helper' -> 'clone'.\x0a        'start' -> [ :e :ui | self startResizing: ui helper ].\x0a        'drag' -> [ :e :ui | self resize: ui offset top ] }",
-messageSends: ["draggable:", "asJQuery", "->", "parent", "startResizing:", "helper", "resize:", "top", "offset"],
+messageSends: ["draggable:", "asJQuery", "parent", "startResizing:", "helper", "resize:", "top", "offset"],
 referencedClasses: []
 }),
 globals.HLHorizontalSplitter);
@@ -551,29 +542,20 @@ protocol: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$4,$5,$6,$2;
+var $1;
 $1=_st(self["@splitter"])._asJQuery();
 $ctx1.sendIdx["asJQuery"]=1;
-$3="axis".__minus_gt("x");
-$ctx1.sendIdx["->"]=1;
-$4="containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent());
-$ctx1.sendIdx["->"]=2;
-$5="helper".__minus_gt("clone");
-$ctx1.sendIdx["->"]=3;
-$6="start".__minus_gt((function(e,ui){
+_st($1)._draggable_(globals.HashedCollection._newFromPairs_(["axis","x","containment",_st(_st(self["@splitter"])._asJQuery())._parent(),"helper","clone","start",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}));
-$ctx1.sendIdx["->"]=4;
-$2=globals.HashedCollection._from_([$3,$4,$5,$6,"drag".__minus_gt((function(e,ui){
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}),"drag",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._resize_(_st(_st(ui)._offset())._left());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})}))]);
-_st($1)._draggable_($2);
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})})]));
 return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},globals.HLVerticalSplitter)})},
 args: [],
 source: "setupSplitter\x0a\x09splitter asJQuery draggable: #{ \x0a    \x09'axis' -> 'x'. \x0a        'containment' -> splitter asJQuery parent.\x0a        'helper' -> 'clone'.\x0a        'start' -> [ :e :ui | self startResizing: ui helper ].\x0a        'drag' -> [ :e :ui | self resize: (ui offset left) ] }",
-messageSends: ["draggable:", "asJQuery", "->", "parent", "startResizing:", "helper", "resize:", "left", "offset"],
+messageSends: ["draggable:", "asJQuery", "parent", "startResizing:", "helper", "resize:", "left", "offset"],
 referencedClasses: []
 }),
 globals.HLVerticalSplitter);

+ 29 - 158
js/Helios-Workspace.js

@@ -392,35 +392,15 @@ fn: function (){
 var self=this;
 function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $3,$2,$4,$5,$6,$7,$8,$9,$10,$11,$12,$1;
-$3="helios.codeMirrorTheme"._settingValueIfAbsent_("default helios");
+var $2,$1;
+$2="helios.codeMirrorTheme"._settingValueIfAbsent_("default helios");
 $ctx1.sendIdx["settingValueIfAbsent:"]=1;
-$2="theme".__minus_gt($3);
-$ctx1.sendIdx["->"]=1;
-$4="mode".__minus_gt("text/x-stsrc");
-$ctx1.sendIdx["->"]=2;
-$5="lineNumbers".__minus_gt(true);
-$ctx1.sendIdx["->"]=3;
-$6="enterMode".__minus_gt("flat");
-$ctx1.sendIdx["->"]=4;
-$7="indentWithTabs".__minus_gt(true);
-$ctx1.sendIdx["->"]=5;
-$8="indentUnit".__minus_gt((4));
-$ctx1.sendIdx["->"]=6;
-$9="matchBrackets".__minus_gt(true);
-$ctx1.sendIdx["->"]=7;
-$10="electricChars".__minus_gt(false);
-$ctx1.sendIdx["->"]=8;
-$11="keyMap".__minus_gt("Amber");
-$ctx1.sendIdx["->"]=9;
-$12="extraKeys".__minus_gt(_st($HashedCollection())._with_(_st("helios.completionKey"._settingValueIfAbsent_("Shift-Space")).__minus_gt("autocomplete")));
-$ctx1.sendIdx["->"]=10;
-$1=globals.HashedCollection._from_([$2,$4,$5,$6,$7,$8,$9,$10,$11,$12]);
+$1=globals.HashedCollection._newFromPairs_(["theme",$2,"mode","text/x-stsrc","lineNumbers",true,"enterMode","flat","indentWithTabs",true,"indentUnit",(4),"matchBrackets",true,"electricChars",false,"keyMap","Amber","extraKeys",_st($HashedCollection())._with_(_st("helios.completionKey"._settingValueIfAbsent_("Shift-Space")).__minus_gt("autocomplete"))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"editorOptions",{},globals.HLCodeWidget)})},
 args: [],
 source: "editorOptions\x0a\x09^ #{\x0a\x09\x09'theme' -> ('helios.codeMirrorTheme' settingValueIfAbsent: 'default helios').\x0a\x09\x09'mode' -> 'text/x-stsrc'.\x0a        'lineNumbers' -> true.\x0a        'enterMode' -> 'flat'.\x0a        'indentWithTabs' -> true.\x0a\x09\x09'indentUnit' -> 4.\x0a        'matchBrackets' -> true.\x0a        'electricChars' -> false.\x0a\x09\x09'keyMap' -> 'Amber'.\x0a\x09\x09'extraKeys' -> (HashedCollection with: ('helios.completionKey' settingValueIfAbsent: 'Shift-Space') -> 'autocomplete')\x0a\x09}",
-messageSends: ["->", "settingValueIfAbsent:", "with:"],
+messageSends: ["settingValueIfAbsent:", "with:", "->"],
 referencedClasses: ["HashedCollection"]
 }),
 globals.HLCodeWidget);
@@ -651,7 +631,7 @@ var self=this;
 var start,stop,currentLine;
 function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$4,$3,$5,$6,$7,$8,$10,$9,$11,$12,$13,$15,$14;
+var $1,$2,$4,$3,$5,$6,$7,$8,$9,$10,$12,$11;
 $1=_st(self["@editor"])._getCursor_(false);
 $ctx1.sendIdx["getCursor:"]=1;
 currentLine=_st($1)._line();
@@ -674,32 +654,28 @@ $7=_st(_st(self["@editor"])._getLine_(currentLine))._size();
 $ctx2.sendIdx["size"]=1;
 _st($6)._at_put_("ch",$7);
 $ctx2.sendIdx["at:put:"]=3;
-$8=self["@editor"];
-$10="line".__minus_gt(currentLine);
-$ctx2.sendIdx["->"]=1;
-$9=globals.HashedCollection._from_([$10,"ch".__minus_gt((0))]);
-return _st($8)._setSelection_end_($9,start);
+return _st(self["@editor"])._setSelection_end_(globals.HashedCollection._newFromPairs_(["line",currentLine,"ch",(0)]),start);
 $ctx2.sendIdx["setSelection:end:"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);
 $ctx1.sendIdx["at:put:"]=4;
-$11=stop;
-$12=_st(_st(_st(start)._at_("ch")).__plus(_st(aString)._size())).__plus((2));
+$8=stop;
+$9=_st(_st(_st(start)._at_("ch")).__plus(_st(aString)._size())).__plus((2));
 $ctx1.sendIdx["+"]=1;
-_st($11)._at_put_("ch",$12);
-$13=self["@editor"];
-$15=_st(_st(_st(self["@editor"])._getSelection()).__comma(" ")).__comma(aString);
+_st($8)._at_put_("ch",$9);
+$10=self["@editor"];
+$12=_st(_st(_st(self["@editor"])._getSelection()).__comma(" ")).__comma(aString);
 $ctx1.sendIdx[","]=2;
-$14=_st($15).__comma(" ");
+$11=_st($12).__comma(" ");
 $ctx1.sendIdx[","]=1;
-_st($13)._replaceSelection_($14);
+_st($10)._replaceSelection_($11);
 _st(self["@editor"])._setCursor_(_st(self["@editor"])._getCursor_(true));
 _st(self["@editor"])._setSelection_end_(stop,start);
 return self}, function($ctx1) {$ctx1.fill(self,"print:",{aString:aString,start:start,stop:stop,currentLine:currentLine},globals.HLCodeWidget)})},
 args: ["aString"],
 source: "print: aString\x0a\x09| start stop currentLine |\x0a    currentLine := (editor getCursor: false) line.\x0a\x09start := HashedCollection new.\x0a\x09start at: 'line' put: currentLine.\x0a\x09start at: 'ch' put: (editor getCursor: false) ch.\x0a    (editor getSelection) ifEmpty: [\x0a    \x09\x22select current line if selection is empty\x22\x0a    \x09start at: 'ch' put: (editor getLine: currentLine) size.\x0a        editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.\x0a    ].\x0a\x09stop := HashedCollection new.\x0a\x09stop at: 'line' put: currentLine.\x0a\x09stop at: 'ch' put: ((start at: 'ch') + aString size + 2).\x0a\x0a\x09editor replaceSelection: (editor getSelection, ' ', aString, ' ').\x0a\x09editor setCursor: (editor getCursor: true).\x0a\x09editor setSelection: stop end: start",
-messageSends: ["line", "getCursor:", "new", "at:put:", "ch", "ifEmpty:", "getSelection", "size", "getLine:", "setSelection:end:", "->", "+", "at:", "replaceSelection:", ",", "setCursor:"],
+messageSends: ["line", "getCursor:", "new", "at:put:", "ch", "ifEmpty:", "getSelection", "size", "getLine:", "setSelection:end:", "+", "at:", "replaceSelection:", ",", "setCursor:"],
 referencedClasses: ["HashedCollection"]
 }),
 globals.HLCodeWidget);
@@ -1042,7 +1018,7 @@ var cursor,token,completions;
 function $CodeMirror(){return globals.CodeMirror||(typeof CodeMirror=="undefined"?nil:CodeMirror)}
 function $HLCodeWidget(){return globals.HLCodeWidget||(typeof HLCodeWidget=="undefined"?nil:HLCodeWidget)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$4,$3,$2,$5,$7,$10,$11,$9,$8,$6;
+var $1,$4,$3,$2,$5,$7,$9,$10,$8,$6;
 cursor=_st(anEditor)._getCursor();
 token=_st(anEditor)._getTokenAt_(cursor);
 $1=token;
@@ -1058,22 +1034,19 @@ completions=_st($HLCodeWidget())._variableHintFor_token_(anEditor,token);
 } else {
 completions=_st($HLCodeWidget())._messageHintFor_token_(anEditor,token);
 };
-$7="list".__minus_gt(completions);
-$ctx1.sendIdx["->"]=1;
-$10=_st($CodeMirror())._basicAt_("Pos");
+$7=completions;
+$9=_st($CodeMirror())._basicAt_("Pos");
 $ctx1.sendIdx["basicAt:"]=2;
-$11=_st(cursor)._line();
+$10=_st(cursor)._line();
 $ctx1.sendIdx["line"]=1;
-$9=_st($10)._value_value_($11,_st(token)._end());
+$8=_st($9)._value_value_($10,_st(token)._end());
 $ctx1.sendIdx["value:value:"]=2;
-$8="from".__minus_gt($9);
-$ctx1.sendIdx["->"]=2;
-$6=globals.HashedCollection._from_([$7,$8,"to".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start()))]);
+$6=globals.HashedCollection._newFromPairs_(["list",$7,"from",$8,"to",_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start())]);
 return $6;
 }, function($ctx1) {$ctx1.fill(self,"hintFor:options:",{anEditor:anEditor,options:options,cursor:cursor,token:token,completions:completions},globals.HLCodeWidget.klass)})},
 args: ["anEditor", "options"],
 source: "hintFor: anEditor options: options\x0a\x09| cursor token completions |\x0a\x09\x0a\x09cursor := anEditor getCursor.\x0a\x09token := anEditor getTokenAt: cursor.\x0a\x09token at: 'state' put: ((CodeMirror basicAt: 'innerMode')\x0a\x09\x09value: anEditor getMode value: (token at: 'state')) state.\x0a\x09\x0a\x09completions := token type = 'variable' \x0a\x09\x09ifTrue: [ HLCodeWidget variableHintFor: anEditor token: token ]\x0a\x09\x09ifFalse: [ HLCodeWidget messageHintFor: anEditor token: token ].\x0a\x09\x0a\x09^ #{\x0a\x09\x09'list' -> completions.\x0a\x09\x09'from' -> ((CodeMirror basicAt: 'Pos') value: cursor line value: token end).\x0a\x09\x09'to' -> ((CodeMirror basicAt: 'Pos') value: cursor line value: token start)\x0a\x09}",
-messageSends: ["getCursor", "getTokenAt:", "at:put:", "state", "value:value:", "basicAt:", "getMode", "at:", "ifTrue:ifFalse:", "=", "type", "variableHintFor:token:", "messageHintFor:token:", "->", "line", "end", "start"],
+messageSends: ["getCursor", "getTokenAt:", "at:put:", "state", "value:value:", "basicAt:", "getMode", "at:", "ifTrue:ifFalse:", "=", "type", "variableHintFor:token:", "messageHintFor:token:", "line", "end", "start"],
 referencedClasses: ["CodeMirror", "HLCodeWidget"]
 }),
 globals.HLCodeWidget.klass);
@@ -1128,64 +1101,13 @@ selector: "macKeyMap",
 protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$1;
-$2="Alt-Backspace".__minus_gt("delWordBefore");
-$ctx1.sendIdx["->"]=1;
-$3="Alt-Delete".__minus_gt("delWordAfter");
-$ctx1.sendIdx["->"]=2;
-$4="Alt-Left".__minus_gt("goWordLeft");
-$ctx1.sendIdx["->"]=3;
-$5="Alt-Right".__minus_gt("goWordRight");
-$ctx1.sendIdx["->"]=4;
-$6="Cmd-A".__minus_gt("selectAll");
-$ctx1.sendIdx["->"]=5;
-$7="Cmd-Alt-F".__minus_gt("replace");
-$ctx1.sendIdx["->"]=6;
-$8="Cmd-D".__minus_gt("doIt");
-$ctx1.sendIdx["->"]=7;
-$9="Cmd-Down".__minus_gt("goDocEnd");
-$ctx1.sendIdx["->"]=8;
-$10="Cmd-End".__minus_gt("goDocEnd");
-$ctx1.sendIdx["->"]=9;
-$11="Cmd-F".__minus_gt("find");
-$ctx1.sendIdx["->"]=10;
-$12="Cmd-G".__minus_gt("findNext");
-$ctx1.sendIdx["->"]=11;
-$13="Cmd-I".__minus_gt("inspectIt");
-$ctx1.sendIdx["->"]=12;
-$14="Cmd-Left".__minus_gt("goLineStart");
-$ctx1.sendIdx["->"]=13;
-$15="Cmd-P".__minus_gt("printIt");
-$ctx1.sendIdx["->"]=14;
-$16="Cmd-Right".__minus_gt("goLineEnd");
-$ctx1.sendIdx["->"]=15;
-$17="Cmd-S".__minus_gt("saveIt");
-$ctx1.sendIdx["->"]=16;
-$18="Cmd-Up".__minus_gt("goDocStart");
-$ctx1.sendIdx["->"]=17;
-$19="Cmd-Y".__minus_gt("redo");
-$ctx1.sendIdx["->"]=18;
-$20="Cmd-Z".__minus_gt("undo");
-$ctx1.sendIdx["->"]=19;
-$21="Cmd-[".__minus_gt("indentLess");
-$ctx1.sendIdx["->"]=20;
-$22="Cmd-]".__minus_gt("indentMore");
-$ctx1.sendIdx["->"]=21;
-$23="Ctrl-Alt-Backspace".__minus_gt("delWordAfter");
-$ctx1.sendIdx["->"]=22;
-$24="Shift-Cmd-Alt-F".__minus_gt("replaceAll");
-$ctx1.sendIdx["->"]=23;
-$25="Shift-Cmd-G".__minus_gt("findPrev");
-$ctx1.sendIdx["->"]=24;
-$26="Shift-Cmd-Z".__minus_gt("redo");
-$ctx1.sendIdx["->"]=25;
-$1=globals.HashedCollection._from_([$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,"fallthrough".__minus_gt(["basic","emacsy"])]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["Alt-Backspace","delWordBefore","Alt-Delete","delWordAfter","Alt-Left","goWordLeft","Alt-Right","goWordRight","Cmd-A","selectAll","Cmd-Alt-F","replace","Cmd-D","doIt","Cmd-Down","goDocEnd","Cmd-End","goDocEnd","Cmd-F","find","Cmd-G","findNext","Cmd-I","inspectIt","Cmd-Left","goLineStart","Cmd-P","printIt","Cmd-Right","goLineEnd","Cmd-S","saveIt","Cmd-Up","goDocStart","Cmd-Y","redo","Cmd-Z","undo","Cmd-[","indentLess","Cmd-]","indentMore","Ctrl-Alt-Backspace","delWordAfter","Shift-Cmd-Alt-F","replaceAll","Shift-Cmd-G","findPrev","Shift-Cmd-Z","redo","fallthrough",["basic","emacsy"]]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"macKeyMap",{},globals.HLCodeWidget.klass)})},
+},
 args: [],
 source: "macKeyMap\x0a\x09^ #{\x0a\x09\x09'Alt-Backspace'\x09\x09\x09-> 'delWordBefore'.\x0a\x09\x09'Alt-Delete'\x09\x09\x09-> 'delWordAfter'. \x0a\x09\x09'Alt-Left'\x09\x09\x09\x09-> 'goWordLeft'.\x0a\x09\x09'Alt-Right'\x09\x09\x09\x09-> 'goWordRight'. \x0a\x09\x09'Cmd-A'\x09\x09\x09\x09\x09-> 'selectAll'. \x0a\x09\x09'Cmd-Alt-F'\x09\x09\x09\x09-> 'replace'. \x0a\x09\x09'Cmd-D'\x09\x09\x09\x09\x09-> 'doIt'. \x0a\x09\x09'Cmd-Down'\x09\x09\x09\x09-> 'goDocEnd'. \x0a\x09\x09'Cmd-End'\x09\x09\x09\x09-> 'goDocEnd'. \x0a\x09\x09'Cmd-F'\x09\x09\x09\x09\x09-> 'find'.\x0a\x09\x09'Cmd-G'\x09\x09\x09\x09\x09-> 'findNext'. \x0a\x09\x09'Cmd-I'\x09\x09\x09\x09\x09-> 'inspectIt'. \x0a\x09\x09'Cmd-Left'\x09\x09\x09\x09-> 'goLineStart'. \x0a\x09\x09'Cmd-P'\x09\x09\x09\x09\x09-> 'printIt'. \x0a\x09\x09'Cmd-Right'\x09\x09\x09\x09-> 'goLineEnd'. \x0a\x09\x09'Cmd-S'\x09\x09\x09\x09\x09-> 'saveIt'. \x0a\x09\x09'Cmd-Up'\x09\x09\x09\x09-> 'goDocStart'. \x0a\x09\x09'Cmd-Y'\x09\x09\x09\x09\x09-> 'redo'.\x0a\x09\x09'Cmd-Z'\x09\x09\x09\x09\x09-> 'undo'. \x0a\x09\x09'Cmd-['\x09\x09\x09\x09\x09-> 'indentLess'. \x0a\x09\x09'Cmd-]'\x09\x09\x09\x09\x09-> 'indentMore'.\x0a\x09\x09'Ctrl-Alt-Backspace'\x09-> 'delWordAfter'. \x0a\x09\x09'Shift-Cmd-Alt-F'\x09\x09-> 'replaceAll'.\x0a\x09\x09'Shift-Cmd-G'\x09\x09\x09-> 'findPrev'. \x0a\x09\x09'Shift-Cmd-Z'\x09\x09\x09-> 'redo'. \x0a    \x09'fallthrough' \x09\x09\x09-> { 'basic'. 'emacsy' }\x0a  }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HLCodeWidget.klass);
@@ -1214,64 +1136,13 @@ selector: "pcKeyMap",
 protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$1;
-$2="Alt-Left".__minus_gt("goLineStart");
-$ctx1.sendIdx["->"]=1;
-$3="Alt-Right".__minus_gt("goLineEnd");
-$ctx1.sendIdx["->"]=2;
-$4="Alt-Up".__minus_gt("goDocStart");
-$ctx1.sendIdx["->"]=3;
-$5="Ctrl-A".__minus_gt("selectAll");
-$ctx1.sendIdx["->"]=4;
-$6="Ctrl-Backspace".__minus_gt("delWordBefore");
-$ctx1.sendIdx["->"]=5;
-$7="Ctrl-D".__minus_gt("doIt");
-$ctx1.sendIdx["->"]=6;
-$8="Ctrl-Delete".__minus_gt("delWordAfter");
-$ctx1.sendIdx["->"]=7;
-$9="Ctrl-Down".__minus_gt("goDocEnd");
-$ctx1.sendIdx["->"]=8;
-$10="Ctrl-End".__minus_gt("goDocEnd");
-$ctx1.sendIdx["->"]=9;
-$11="Ctrl-F".__minus_gt("find");
-$ctx1.sendIdx["->"]=10;
-$12="Ctrl-G".__minus_gt("findNext");
-$ctx1.sendIdx["->"]=11;
-$13="Ctrl-I".__minus_gt("inspectIt");
-$ctx1.sendIdx["->"]=12;
-$14="Ctrl-Home".__minus_gt("goDocStart");
-$ctx1.sendIdx["->"]=13;
-$15="Ctrl-Left".__minus_gt("goWordLeft");
-$ctx1.sendIdx["->"]=14;
-$16="Ctrl-P".__minus_gt("printIt");
-$ctx1.sendIdx["->"]=15;
-$17="Ctrl-Right".__minus_gt("goWordRight");
-$ctx1.sendIdx["->"]=16;
-$18="Ctrl-S".__minus_gt("saveIt");
-$ctx1.sendIdx["->"]=17;
-$19="Ctrl-Y".__minus_gt("redo");
-$ctx1.sendIdx["->"]=18;
-$20="Ctrl-Z".__minus_gt("undo");
-$ctx1.sendIdx["->"]=19;
-$21="Ctrl-[".__minus_gt("indentLess");
-$ctx1.sendIdx["->"]=20;
-$22="Ctrl-]".__minus_gt("indentMore");
-$ctx1.sendIdx["->"]=21;
-$23="Shift-Ctrl-F".__minus_gt("replace");
-$ctx1.sendIdx["->"]=22;
-$24="Shift-Ctrl-G".__minus_gt("findPrev");
-$ctx1.sendIdx["->"]=23;
-$25="Shift-Ctrl-R".__minus_gt("replaceAll");
-$ctx1.sendIdx["->"]=24;
-$26="Shift-Ctrl-Z".__minus_gt("redo");
-$ctx1.sendIdx["->"]=25;
-$1=globals.HashedCollection._from_([$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,"fallthrough".__minus_gt(["basic"])]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["Alt-Left","goLineStart","Alt-Right","goLineEnd","Alt-Up","goDocStart","Ctrl-A","selectAll","Ctrl-Backspace","delWordBefore","Ctrl-D","doIt","Ctrl-Delete","delWordAfter","Ctrl-Down","goDocEnd","Ctrl-End","goDocEnd","Ctrl-F","find","Ctrl-G","findNext","Ctrl-I","inspectIt","Ctrl-Home","goDocStart","Ctrl-Left","goWordLeft","Ctrl-P","printIt","Ctrl-Right","goWordRight","Ctrl-S","saveIt","Ctrl-Y","redo","Ctrl-Z","undo","Ctrl-[","indentLess","Ctrl-]","indentMore","Shift-Ctrl-F","replace","Shift-Ctrl-G","findPrev","Shift-Ctrl-R","replaceAll","Shift-Ctrl-Z","redo","fallthrough",["basic"]]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"pcKeyMap",{},globals.HLCodeWidget.klass)})},
+},
 args: [],
 source: "pcKeyMap\x0a\x09^ #{\x0a\x09\x09'Alt-Left' -> \x09\x09'goLineStart'. \x0a\x09\x09'Alt-Right' -> \x09\x09'goLineEnd'.\x0a\x09\x09'Alt-Up' -> \x09\x09'goDocStart'. \x0a\x09\x09'Ctrl-A' -> \x09\x09'selectAll'. \x0a\x09\x09'Ctrl-Backspace' -> 'delWordBefore'. \x0a\x09\x09'Ctrl-D' -> \x09\x09'doIt'. \x0a\x09\x09'Ctrl-Delete' -> \x09\x09'delWordAfter'. \x0a\x09\x09'Ctrl-Down' -> \x09\x09'goDocEnd'.\x0a\x09\x09'Ctrl-End' -> \x09\x09'goDocEnd'. \x0a\x09\x09'Ctrl-F' -> \x09\x09'find'.\x0a\x09\x09'Ctrl-G' -> \x09\x09'findNext'. \x0a\x09\x09'Ctrl-I' -> \x09\x09'inspectIt'.\x0a\x09\x09'Ctrl-Home' -> \x09\x09'goDocStart'. \x0a\x09\x09'Ctrl-Left' -> \x09\x09'goWordLeft'. \x0a\x09\x09'Ctrl-P' -> \x09\x09'printIt'.\x0a\x09\x09'Ctrl-Right' -> \x09'goWordRight'. \x0a\x09\x09'Ctrl-S' -> \x09\x09'saveIt'. \x0a\x09\x09'Ctrl-Y' -> \x09\x09'redo'.\x0a\x09\x09'Ctrl-Z' -> \x09\x09'undo'. \x0a\x09\x09'Ctrl-[' -> \x09\x09'indentLess'. \x0a\x09\x09'Ctrl-]' -> \x09\x09'indentMore'.\x0a\x09\x09'Shift-Ctrl-F' -> \x09'replace'. \x0a\x09\x09'Shift-Ctrl-G' -> \x09'findPrev'. \x0a\x09\x09'Shift-Ctrl-R' -> \x09'replaceAll'.\x0a\x09\x09'Shift-Ctrl-Z' -> \x09'redo'. \x0a\x09\x09'fallthrough' -> \x09#('basic')\x0a}",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HLCodeWidget.klass);

+ 12 - 23
js/IDE.js

@@ -784,7 +784,7 @@ var self=this;
 var start,stop,currentLine;
 function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$4,$3,$5,$6,$7,$8,$10,$9,$11,$12,$13,$15,$14;
+var $1,$2,$4,$3,$5,$6,$7,$8,$9,$10,$12,$11;
 $1=_st(self["@editor"])._getCursor_(false);
 $ctx1.sendIdx["getCursor:"]=1;
 currentLine=_st($1)._line();
@@ -807,32 +807,28 @@ $7=_st(_st(self["@editor"])._getLine_(currentLine))._size();
 $ctx2.sendIdx["size"]=1;
 _st($6)._at_put_("ch",$7);
 $ctx2.sendIdx["at:put:"]=3;
-$8=self["@editor"];
-$10="line".__minus_gt(currentLine);
-$ctx2.sendIdx["->"]=1;
-$9=globals.HashedCollection._from_([$10,"ch".__minus_gt((0))]);
-return _st($8)._setSelection_end_($9,start);
+return _st(self["@editor"])._setSelection_end_(globals.HashedCollection._newFromPairs_(["line",currentLine,"ch",(0)]),start);
 $ctx2.sendIdx["setSelection:end:"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);
 $ctx1.sendIdx["at:put:"]=4;
-$11=stop;
-$12=_st(_st(_st(start)._at_("ch")).__plus(_st(aString)._size())).__plus((2));
+$8=stop;
+$9=_st(_st(_st(start)._at_("ch")).__plus(_st(aString)._size())).__plus((2));
 $ctx1.sendIdx["+"]=1;
-_st($11)._at_put_("ch",$12);
-$13=self["@editor"];
-$15=_st(_st(_st(self["@editor"])._getSelection()).__comma(" ")).__comma(aString);
+_st($8)._at_put_("ch",$9);
+$10=self["@editor"];
+$12=_st(_st(_st(self["@editor"])._getSelection()).__comma(" ")).__comma(aString);
 $ctx1.sendIdx[","]=2;
-$14=_st($15).__comma(" ");
+$11=_st($12).__comma(" ");
 $ctx1.sendIdx[","]=1;
-_st($13)._replaceSelection_($14);
+_st($10)._replaceSelection_($11);
 _st(self["@editor"])._setCursor_(_st(self["@editor"])._getCursor_(true));
 _st(self["@editor"])._setSelection_end_(stop,start);
 return self}, function($ctx1) {$ctx1.fill(self,"print:",{aString:aString,start:start,stop:stop,currentLine:currentLine},globals.SourceArea)})},
 args: ["aString"],
 source: "print: aString\x0a\x09| start stop currentLine |\x0a\x09currentLine := (editor getCursor: false) line.\x0a\x09start := HashedCollection new.\x0a\x09start at: 'line' put: currentLine.\x0a\x09start at: 'ch' put: (editor getCursor: false) ch.\x0a\x09(editor getSelection) ifEmpty: [\x0a\x09\x09\x22select current line if selection is empty\x22\x0a\x09\x09start at: 'ch' put: (editor getLine: currentLine) size.\x0a\x09\x09editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.\x0a\x09].\x0a\x09stop := HashedCollection new.\x0a\x09stop at: 'line' put: currentLine.\x0a\x09stop at: 'ch' put: ((start at: 'ch') + aString size + 2).\x0a\x0a\x09editor replaceSelection: (editor getSelection, ' ', aString, ' ').\x0a\x09editor setCursor: (editor getCursor: true).\x0a\x09editor setSelection: stop end: start",
-messageSends: ["line", "getCursor:", "new", "at:put:", "ch", "ifEmpty:", "getSelection", "size", "getLine:", "setSelection:end:", "->", "+", "at:", "replaceSelection:", ",", "setCursor:"],
+messageSends: ["line", "getCursor:", "new", "at:put:", "ch", "ifEmpty:", "getSelection", "size", "getLine:", "setSelection:end:", "+", "at:", "replaceSelection:", ",", "setCursor:"],
 referencedClasses: ["HashedCollection"]
 }),
 globals.SourceArea);
@@ -1214,18 +1210,11 @@ protocol: 'actions',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$4,$2;
-$1="#amber"._asJQuery();
-$3="handles".__minus_gt("n");
-$ctx1.sendIdx["->"]=1;
-$4="resize".__minus_gt(aBlock);
-$ctx1.sendIdx["->"]=2;
-$2=globals.HashedCollection._from_([$3,$4,"minHeight".__minus_gt((230))]);
-_st($1)._resizable_($2);
+_st("#amber"._asJQuery())._resizable_(globals.HashedCollection._newFromPairs_(["handles","n","resize",aBlock,"minHeight",(230)]));
 return self}, function($ctx1) {$ctx1.fill(self,"onResize:",{aBlock:aBlock},globals.TabManager)})},
 args: ["aBlock"],
 source: "onResize: aBlock\x0a\x09'#amber' asJQuery resizable: #{\x0a\x09\x09'handles' -> 'n'.\x0a\x09\x09'resize' -> aBlock.\x0a\x09\x09'minHeight' -> 230\x0a\x09}",
-messageSends: ["resizable:", "asJQuery", "->"],
+messageSends: ["resizable:", "asJQuery"],
 referencedClasses: []
 }),
 globals.TabManager);

+ 11 - 20
js/Kernel-ImportExport.js

@@ -1431,30 +1431,21 @@ protocol: 'private',
 fn: function (aURL,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$5,$8,$7,$6,$1;
-$2="url".__minus_gt(aURL);
-$ctx1.sendIdx["->"]=1;
-$3="type".__minus_gt("PUT");
-$ctx1.sendIdx["->"]=2;
-$4="data".__minus_gt(aString);
-$ctx1.sendIdx["->"]=3;
-$5="contentType".__minus_gt("text/plain;charset=UTF-8");
-$ctx1.sendIdx["->"]=4;
-$1=globals.HashedCollection._from_([$2,$3,$4,$5,"error".__minus_gt((function(xhr){
+var $3,$2,$1;
+self._ajax_(globals.HashedCollection._newFromPairs_(["url",aURL,"type","PUT","data",aString,"contentType","text/plain;charset=UTF-8","error",(function(xhr){
 return smalltalk.withContext(function($ctx2) {
-$8=_st("Commiting ".__comma(aURL)).__comma(" failed with reason: \x22");
+$3=_st("Commiting ".__comma(aURL)).__comma(" failed with reason: \x22");
 $ctx2.sendIdx[","]=3;
-$7=_st($8).__comma(_st(xhr)._responseText());
+$2=_st($3).__comma(_st(xhr)._responseText());
 $ctx2.sendIdx[","]=2;
-$6=_st($7).__comma("\x22");
+$1=_st($2).__comma("\x22");
 $ctx2.sendIdx[","]=1;
-return self._alert_($6);
-}, function($ctx2) {$ctx2.fillBlock({xhr:xhr},$ctx1,1)})}))]);
-self._ajax_($1);
+return self._alert_($1);
+}, function($ctx2) {$ctx2.fillBlock({xhr:xhr},$ctx1,1)})})]));
 return self}, function($ctx1) {$ctx1.fill(self,"ajaxPutAt:data:",{aURL:aURL,aString:aString},globals.PackageHandler)})},
 args: ["aURL", "aString"],
 source: "ajaxPutAt: aURL data: aString\x0a\x09self\x0a\x09\x09ajax: #{\x0a\x09\x09\x09'url' -> aURL.\x0a\x09\x09\x09'type' -> 'PUT'.\x0a\x09\x09\x09'data' -> aString.\x0a\x09\x09\x09'contentType' -> 'text/plain;charset=UTF-8'.\x0a\x09\x09\x09'error' -> [ :xhr | self alert: 'Commiting ' , aURL , ' failed with reason: \x22' , (xhr responseText) , '\x22' ] }",
-messageSends: ["ajax:", "->", "alert:", ",", "responseText"],
+messageSends: ["ajax:", "alert:", ",", "responseText"],
 referencedClasses: []
 }),
 globals.PackageHandler);
@@ -1863,12 +1854,12 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=globals.HashedCollection._from_(["type".__minus_gt(self._type())]);
+$1=globals.HashedCollection._newFromPairs_(["type",self._type()]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asJSON",{},globals.PackageTransport)})},
 args: [],
 source: "asJSON\x0a\x09^ #{ 'type' -> self type }",
-messageSends: ["->", "type"],
+messageSends: ["type"],
 referencedClasses: []
 }),
 globals.PackageTransport);
@@ -2111,7 +2102,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 globals.PackageTransport.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
-self["@registry"]=globals.HashedCollection._from_([]);
+self["@registry"]=globals.HashedCollection._newFromPairs_([]);
 self._register();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.PackageTransport.klass)})},
 args: [],

+ 28 - 86
js/Kernel-Tests.js

@@ -2862,17 +2862,11 @@ fn: function (){
 var self=this;
 var associations;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$5,$4;
+var $1;
 $1="a".__minus_gt((1));
 $ctx1.sendIdx["->"]=1;
-$2="b".__minus_gt((2));
-$ctx1.sendIdx["->"]=2;
-associations=[$1,$2];
-$3=_st(_st(self._class())._collectionClass())._from_(associations);
-$5="a".__minus_gt((1));
-$ctx1.sendIdx["->"]=3;
-$4=globals.HashedCollection._from_([$5,"b".__minus_gt((2))]);
-self._assertSameContents_as_($3,$4);
+associations=[$1,"b".__minus_gt((2))];
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._from_(associations),globals.HashedCollection._newFromPairs_(["a",(1),"b",(2)]));
 return self}, function($ctx1) {$ctx1.fill(self,"testFrom",{associations:associations},globals.AssociativeCollectionTest)})},
 args: [],
 source: "testFrom\x0a\x22Accept a collection of associations.\x22\x0a| associations |\x0aassociations := { 'a' -> 1. 'b' -> 2 }.\x0aself assertSameContents: ( self class collectionClass from: associations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
@@ -2916,17 +2910,12 @@ fn: function (){
 var self=this;
 var flattenedAssociations;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$2;
 flattenedAssociations=["a",(1),"b",(2)];
-$1=_st(_st(self._class())._collectionClass())._newFromPairs_(flattenedAssociations);
-$3="a".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$2=globals.HashedCollection._from_([$3,"b".__minus_gt((2))]);
-self._assertSameContents_as_($1,$2);
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._newFromPairs_(flattenedAssociations),globals.HashedCollection._newFromPairs_(["a",(1),"b",(2)]));
 return self}, function($ctx1) {$ctx1.fill(self,"testNewFromPairs",{flattenedAssociations:flattenedAssociations},globals.AssociativeCollectionTest)})},
 args: [],
 source: "testNewFromPairs\x0a\x22Accept an array in which all odd indexes are keys and evens are values.\x22\x0a| flattenedAssociations |\x0aflattenedAssociations := { 'a'. 1. 'b'. 2 }.\x0aself assertSameContents: ( self class collectionClass newFromPairs: flattenedAssociations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
-messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class", "->"],
+messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class"],
 referencedClasses: []
 }),
 globals.AssociativeCollectionTest);
@@ -3390,16 +3379,11 @@ fn: function (){
 var self=this;
 function $Dictionary(){return globals.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-var $3,$2,$1;
-$3="hello".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$2=globals.HashedCollection._from_([$3]);
-$1=_st($2)._asDictionary();
-self._assert_equals_($1,_st($Dictionary())._with_("hello".__minus_gt((1))));
+self._assert_equals_(_st(globals.HashedCollection._newFromPairs_(["hello",(1)]))._asDictionary(),_st($Dictionary())._with_("hello".__minus_gt((1))));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaries",{},globals.DictionaryTest)})},
 args: [],
 source: "testDynamicDictionaries\x0a\x09self assert: #{'hello' -> 1} asDictionary equals: (Dictionary with: 'hello' -> 1)",
-messageSends: ["assert:equals:", "asDictionary", "->", "with:"],
+messageSends: ["assert:equals:", "asDictionary", "with:", "->"],
 referencedClasses: ["Dictionary"]
 }),
 globals.DictionaryTest);
@@ -3429,20 +3413,13 @@ selector: "collection",
 protocol: 'fixture',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$1;
-$2="b".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$3="a".__minus_gt((2));
-$ctx1.sendIdx["->"]=2;
-$4="c".__minus_gt((3));
-$ctx1.sendIdx["->"]=3;
-$1=globals.HashedCollection._from_([$2,$3,$4,"d".__minus_gt((-4))]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["b",(1),"a",(2),"c",(3),"d",(-4)]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"collection",{},globals.HashedCollectionTest)})},
+},
 args: [],
 source: "collection\x0a\x09^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4 }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HashedCollectionTest);
@@ -3470,20 +3447,13 @@ selector: "collectionOfPrintStrings",
 protocol: 'fixture',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$1;
-$2="b".__minus_gt("1");
-$ctx1.sendIdx["->"]=1;
-$3="a".__minus_gt("2");
-$ctx1.sendIdx["->"]=2;
-$4="c".__minus_gt("3");
-$ctx1.sendIdx["->"]=3;
-$1=globals.HashedCollection._from_([$2,$3,$4,"d".__minus_gt("-4")]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["b","1","a","2","c","3","d","-4"]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"collectionOfPrintStrings",{},globals.HashedCollectionTest)})},
+},
 args: [],
 source: "collectionOfPrintStrings\x0a\x09^ #{ 'b' -> '1'. 'a' -> '2'. 'c' -> '3'. 'd' -> '-4' }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HashedCollectionTest);
@@ -3526,26 +3496,13 @@ selector: "collectionWithDuplicates",
 protocol: 'fixture',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$5,$6,$7,$1;
-$2="b".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$3="a".__minus_gt((2));
-$ctx1.sendIdx["->"]=2;
-$4="c".__minus_gt((3));
-$ctx1.sendIdx["->"]=3;
-$5="d".__minus_gt((-4));
-$ctx1.sendIdx["->"]=4;
-$6="e".__minus_gt((1));
-$ctx1.sendIdx["->"]=5;
-$7="f".__minus_gt((2));
-$ctx1.sendIdx["->"]=6;
-$1=globals.HashedCollection._from_([$2,$3,$4,$5,$6,$7,"g".__minus_gt((10))]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["b",(1),"a",(2),"c",(3),"d",(-4),"e",(1),"f",(2),"g",(10)]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"collectionWithDuplicates",{},globals.HashedCollectionTest)})},
+},
 args: [],
 source: "collectionWithDuplicates\x0a\x09^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4. 'e' -> 1. 'f' -> 2. 'g' -> 10 }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HashedCollectionTest);
@@ -3556,22 +3513,13 @@ selector: "collectionWithNewValue",
 protocol: 'fixture',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$4,$5,$1;
-$2="b".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$3="a".__minus_gt((2));
-$ctx1.sendIdx["->"]=2;
-$4="c".__minus_gt((3));
-$ctx1.sendIdx["->"]=3;
-$5="d".__minus_gt((-4));
-$ctx1.sendIdx["->"]=4;
-$1=globals.HashedCollection._from_([$2,$3,$4,$5,"new".__minus_gt("N")]);
+var $1;
+$1=globals.HashedCollection._newFromPairs_(["b",(1),"a",(2),"c",(3),"d",(-4),"new","N"]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"collectionWithNewValue",{},globals.HashedCollectionTest)})},
+},
 args: [],
 source: "collectionWithNewValue\x0a\x09^ #{ 'b' -> 1. 'a' -> 2. 'c' -> 3. 'd' -> -4. 'new' -> 'N' }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HashedCollectionTest);
@@ -3582,14 +3530,13 @@ selector: "sampleNewValueAsCollection",
 protocol: 'fixture',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=globals.HashedCollection._from_(["new".__minus_gt("N")]);
+$1=globals.HashedCollection._newFromPairs_(["new","N"]);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"sampleNewValueAsCollection",{},globals.HashedCollectionTest)})},
+},
 args: [],
 source: "sampleNewValueAsCollection\x0a\x09^ #{ 'new' -> 'N' }",
-messageSends: ["->"],
+messageSends: [],
 referencedClasses: []
 }),
 globals.HashedCollectionTest);
@@ -3602,16 +3549,11 @@ fn: function (){
 var self=this;
 function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $3,$2,$1;
-$3="hello".__minus_gt((1));
-$ctx1.sendIdx["->"]=1;
-$2=globals.HashedCollection._from_([$3]);
-$1=_st($2)._asHashedCollection();
-self._assert_equals_($1,_st($HashedCollection())._with_("hello".__minus_gt((1))));
+self._assert_equals_(_st(globals.HashedCollection._newFromPairs_(["hello",(1)]))._asHashedCollection(),_st($HashedCollection())._with_("hello".__minus_gt((1))));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaries",{},globals.HashedCollectionTest)})},
 args: [],
 source: "testDynamicDictionaries\x0a\x09self assert: #{'hello' -> 1} asHashedCollection equals: (HashedCollection with: 'hello' -> 1)",
-messageSends: ["assert:equals:", "asHashedCollection", "->", "with:"],
+messageSends: ["assert:equals:", "asHashedCollection", "with:", "->"],
 referencedClasses: ["HashedCollection"]
 }),
 globals.HashedCollectionTest);

+ 12 - 0
st/Canvas.st

@@ -927,6 +927,10 @@ width: aString
 
 asJQuery
 	^ self element asJQuery
+!
+
+asJQueryInContext: aContext
+	^ self element asJQueryInContext: aContext
 ! !
 
 !TagBrush methodsFor: 'events'!
@@ -1113,6 +1117,10 @@ asSnippet
 
 asJQuery
 	<return jQuery(self['@jsObject'])>
+!
+
+asJQueryInContext: aContext
+	<return jQuery(self['@jsObject'], aContext)>
 ! !
 
 !Object methodsFor: '*Canvas'!
@@ -1137,5 +1145,9 @@ appendToJQuery: aJQuery
 
 asJQuery
 	<return jQuery(String(self))>
+!
+
+asJQueryInContext: aContext
+	<return jQuery(String(self), aContext)>
 ! !
 

+ 1 - 1
st/Compiler-IR.st

@@ -963,7 +963,7 @@ visitIRDynamicArray: anIRDynamicArray
 !
 
 visitIRDynamicDictionary: anIRDynamicDictionary
-	self stream nextPutAll: 'globals.HashedCollection._from_(['.
+	self stream nextPutAll: 'globals.HashedCollection._newFromPairs_(['.
 		anIRDynamicDictionary instructions
 			do: [ :each | self visit: each ]
 			separatedBy: [ self stream nextPutAll: ',' ].

+ 4 - 8
st/Compiler-Interpreter.st

@@ -619,18 +619,14 @@ visitDynamicArrayNode: aNode
 !
 
 visitDynamicDictionaryNode: aNode
-	| associations hashedCollection |
+	| keyValueList |
 	
-	associations := OrderedCollection new.
-	hashedCollection := HashedCollection new.
+	keyValueList := OrderedCollection new.
 	
 	aNode nodes do: [ :each | 
-		associations add: self pop ].
+		keyValueList add: self pop ].
 	
-	associations reversed do: [ :each |
-		hashedCollection add: each ].
-	
-	self push: hashedCollection
+	self push: (HashedCollection newFromPairs: keyValueList reversed)
 !
 
 visitJSStatementNode: aNode

+ 6 - 2
st/Compiler-Tests.st

@@ -198,11 +198,15 @@ testDynamicArrayElementsOrdered
 testDynamicDictionaryElementsOrdered
 	self should: 'foo
 	| x |
-	x := ''foo''->1.
-	^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }
+	x := ''foo''.
+	^ #{ x->1. ''bar''->(true ifTrue: [ 2 ]) }
 ' return: #{'foo'->1. 'bar'->2}.
 !
 
+testDynamicDictionaryWithMoreArrows
+	self should: 'foo ^ #{1->2->3}' return: (HashedCollection with: 1->2->3)
+!
+
 testGlobalVar
 	self should: 'foo ^ eval class' return: BlockClosure.
 	self should: 'foo ^ Math cos: 0' return: 1.

+ 0 - 4
support/boot.js

@@ -938,10 +938,6 @@ define("amber_vm/boot", [ 'require', './browser-compatibility' ], function (requ
 				error = wrappedError(error);
 			}
 			globals.ErrorHandler._handleError_(error);
-			// Throw the exception anyway, as we want to stop
-			// the execution to avoid infinite loops
-			// Update: do not throw the exception. It's really annoying.
-			// throw error;
 		}
 
 		/* Handle thisContext pseudo variable */

+ 188 - 57
support/parser.js

@@ -317,6 +317,9 @@ globals.SmalltalkParser = (function() {
                                      ._arguments_(pattern[1])
                                      ._nodes_([sequence]);
                          },
+        peg$c136 = function(send) { return send._selector() === "->" },
+        peg$c137 = function(send) { return [send._receiver(), send._arguments()[0]]; },
+        peg$c138 = function(first, others) { return first.concat.apply(first, others); },
 
         peg$currPos          = 0,
         peg$reportedPos      = 0,
@@ -488,7 +491,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsestart() {
       var s0;
 
-      var key    = peg$currPos * 56 + 0,
+      var key    = peg$currPos * 59 + 0,
           cached = peg$cache[key];
 
       if (cached) {
@@ -506,7 +509,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseseparator() {
       var s0, s1;
 
-      var key    = peg$currPos * 56 + 1,
+      var key    = peg$currPos * 59 + 1,
           cached = peg$cache[key];
 
       if (cached) {
@@ -545,7 +548,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsecomments() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 2,
+      var key    = peg$currPos * 59 + 2,
           cached = peg$cache[key];
 
       if (cached) {
@@ -670,7 +673,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsews() {
       var s0, s1;
 
-      var key    = peg$currPos * 56 + 3,
+      var key    = peg$currPos * 59 + 3,
           cached = peg$cache[key];
 
       if (cached) {
@@ -699,7 +702,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseidentifier() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 4,
+      var key    = peg$currPos * 59 + 4,
           cached = peg$cache[key];
 
       if (cached) {
@@ -755,7 +758,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsekeyword() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 5,
+      var key    = peg$currPos * 59 + 5,
           cached = peg$cache[key];
 
       if (cached) {
@@ -794,7 +797,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseselector() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 6,
+      var key    = peg$currPos * 59 + 6,
           cached = peg$cache[key];
 
       if (cached) {
@@ -850,7 +853,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseclassName() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 7,
+      var key    = peg$currPos * 59 + 7,
           cached = peg$cache[key];
 
       if (cached) {
@@ -906,7 +909,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsestring() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 8,
+      var key    = peg$currPos * 59 + 8,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1004,7 +1007,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsesymbol() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 9,
+      var key    = peg$currPos * 59 + 9,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1043,7 +1046,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebareSymbol() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 10,
+      var key    = peg$currPos * 59 + 10,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1079,7 +1082,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsenumber() {
       var s0, s1;
 
-      var key    = peg$currPos * 56 + 11,
+      var key    = peg$currPos * 59 + 11,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1112,7 +1115,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsenumberExp() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 12,
+      var key    = peg$currPos * 59 + 12,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1165,7 +1168,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsehex() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 13,
+      var key    = peg$currPos * 59 + 13,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1240,7 +1243,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsefloat() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 14,
+      var key    = peg$currPos * 59 + 14,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1342,7 +1345,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseinteger() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 15,
+      var key    = peg$currPos * 59 + 15,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1405,7 +1408,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseliteralArray() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 16,
+      var key    = peg$currPos * 59 + 16,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1444,7 +1447,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebareLiteralArray() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 17,
+      var key    = peg$currPos * 59 + 17,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1483,7 +1486,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseliteralArrayRest() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 18,
+      var key    = peg$currPos * 59 + 18,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1581,7 +1584,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsedynamicArray() {
       var s0, s1, s2, s3, s4, s5, s6;
 
-      var key    = peg$currPos * 56 + 19,
+      var key    = peg$currPos * 59 + 19,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1662,7 +1665,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsedynamicDictionary() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 20,
+      var key    = peg$currPos * 59 + 20,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1681,7 +1684,7 @@ globals.SmalltalkParser = (function() {
       if (s1 !== peg$FAILED) {
         s2 = peg$parsews();
         if (s2 !== peg$FAILED) {
-          s3 = peg$parseexpressions();
+          s3 = peg$parseassociations();
           if (s3 === peg$FAILED) {
             s3 = peg$c37;
           }
@@ -1728,7 +1731,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsepseudoVariable() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 21,
+      var key    = peg$currPos * 59 + 21,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1794,7 +1797,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseparseTimeLiteral() {
       var s0;
 
-      var key    = peg$currPos * 56 + 22,
+      var key    = peg$currPos * 59 + 22,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1824,7 +1827,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseruntimeLiteral() {
       var s0;
 
-      var key    = peg$currPos * 56 + 23,
+      var key    = peg$currPos * 59 + 23,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1848,7 +1851,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseliteral() {
       var s0;
 
-      var key    = peg$currPos * 56 + 24,
+      var key    = peg$currPos * 59 + 24,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1869,7 +1872,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsevariable() {
       var s0, s1;
 
-      var key    = peg$currPos * 56 + 25,
+      var key    = peg$currPos * 59 + 25,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1893,7 +1896,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsekeywordPair() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 26,
+      var key    = peg$currPos * 59 + 26,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1938,7 +1941,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebinarySelector() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 27,
+      var key    = peg$currPos * 59 + 27,
           cached = peg$cache[key];
 
       if (cached) {
@@ -1983,7 +1986,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsekeywordPattern() {
       var s0, s1, s2, s3, s4, s5, s6;
 
-      var key    = peg$currPos * 56 + 28,
+      var key    = peg$currPos * 59 + 28,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2070,7 +2073,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebinaryPattern() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 29,
+      var key    = peg$currPos * 59 + 29,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2115,7 +2118,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseunaryPattern() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 30,
+      var key    = peg$currPos * 59 + 30,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2148,7 +2151,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseexpression() {
       var s0;
 
-      var key    = peg$currPos * 56 + 31,
+      var key    = peg$currPos * 59 + 31,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2175,7 +2178,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseexpressionList() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 32,
+      var key    = peg$currPos * 59 + 32,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2226,7 +2229,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseexpressions() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 33,
+      var key    = peg$currPos * 59 + 33,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2264,7 +2267,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseassignment() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 34,
+      var key    = peg$currPos * 59 + 34,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2321,7 +2324,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseret() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 35,
+      var key    = peg$currPos * 59 + 35,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2387,7 +2390,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsetemps() {
       var s0, s1, s2, s3, s4, s5, s6;
 
-      var key    = peg$currPos * 56 + 36,
+      var key    = peg$currPos * 59 + 36,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2485,7 +2488,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseblockParamList() {
       var s0, s1, s2, s3, s4, s5, s6;
 
-      var key    = peg$currPos * 56 + 37,
+      var key    = peg$currPos * 59 + 37,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2605,7 +2608,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsesubexpression() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 38,
+      var key    = peg$currPos * 59 + 38,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2668,7 +2671,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsestatements() {
       var s0, s1, s2, s3, s4, s5, s6, s7;
 
-      var key    = peg$currPos * 56 + 39,
+      var key    = peg$currPos * 59 + 39,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2836,7 +2839,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsesequence() {
       var s0;
 
-      var key    = peg$currPos * 56 + 40,
+      var key    = peg$currPos * 59 + 40,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2857,7 +2860,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsestSequence() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 41,
+      var key    = peg$currPos * 59 + 41,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2908,7 +2911,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseblock() {
       var s0, s1, s2, s3, s4, s5, s6, s7;
 
-      var key    = peg$currPos * 56 + 42,
+      var key    = peg$currPos * 59 + 42,
           cached = peg$cache[key];
 
       if (cached) {
@@ -2989,7 +2992,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseoperand() {
       var s0;
 
-      var key    = peg$currPos * 56 + 43,
+      var key    = peg$currPos * 59 + 43,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3013,7 +3016,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseunaryMessage() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 44,
+      var key    = peg$currPos * 59 + 44,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3067,7 +3070,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseunaryTail() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 45,
+      var key    = peg$currPos * 59 + 45,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3115,7 +3118,7 @@ globals.SmalltalkParser = (function() {
     function peg$parseunarySend() {
       var s0, s1, s2, s3;
 
-      var key    = peg$currPos * 56 + 46,
+      var key    = peg$currPos * 59 + 46,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3157,7 +3160,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebinaryMessage() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 47,
+      var key    = peg$currPos * 59 + 47,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3205,7 +3208,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebinaryTail() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 48,
+      var key    = peg$currPos * 59 + 48,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3241,7 +3244,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsebinarySend() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 49,
+      var key    = peg$currPos * 59 + 49,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3277,7 +3280,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsekeywordMessage() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 50,
+      var key    = peg$currPos * 59 + 50,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3349,7 +3352,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsekeywordSend() {
       var s0, s1, s2;
 
-      var key    = peg$currPos * 56 + 51,
+      var key    = peg$currPos * 59 + 51,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3382,7 +3385,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsemessage() {
       var s0;
 
-      var key    = peg$currPos * 56 + 52,
+      var key    = peg$currPos * 59 + 52,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3406,7 +3409,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsecascade() {
       var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
 
-      var key    = peg$currPos * 56 + 53,
+      var key    = peg$currPos * 59 + 53,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3535,7 +3538,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsejsStatement() {
       var s0, s1, s2, s3, s4;
 
-      var key    = peg$currPos * 56 + 54,
+      var key    = peg$currPos * 59 + 54,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3633,7 +3636,7 @@ globals.SmalltalkParser = (function() {
     function peg$parsemethod() {
       var s0, s1, s2, s3, s4, s5;
 
-      var key    = peg$currPos * 56 + 55,
+      var key    = peg$currPos * 59 + 55,
           cached = peg$cache[key];
 
       if (cached) {
@@ -3690,6 +3693,134 @@ globals.SmalltalkParser = (function() {
       return s0;
     }
 
+    function peg$parseassociationSend() {
+      var s0, s1, s2;
+
+      var key    = peg$currPos * 59 + 56,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsebinarySend();
+      if (s1 !== peg$FAILED) {
+        peg$reportedPos = peg$currPos;
+        s2 = peg$c136(s1);
+        if (s2) {
+          s2 = peg$c112;
+        } else {
+          s2 = peg$c1;
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c137(s1);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseassociationList() {
+      var s0, s1, s2, s3, s4;
+
+      var key    = peg$currPos * 59 + 57,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parsews();
+      if (s1 !== peg$FAILED) {
+        if (input.charCodeAt(peg$currPos) === 46) {
+          s2 = peg$c47;
+          peg$currPos++;
+        } else {
+          s2 = peg$FAILED;
+          if (peg$silentFails === 0) { peg$fail(peg$c48); }
+        }
+        if (s2 !== peg$FAILED) {
+          s3 = peg$parsews();
+          if (s3 !== peg$FAILED) {
+            s4 = peg$parseassociationSend();
+            if (s4 !== peg$FAILED) {
+              peg$reportedPos = s0;
+              s1 = peg$c85(s4);
+              s0 = s1;
+            } else {
+              peg$currPos = s0;
+              s0 = peg$c1;
+            }
+          } else {
+            peg$currPos = s0;
+            s0 = peg$c1;
+          }
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
+    function peg$parseassociations() {
+      var s0, s1, s2, s3;
+
+      var key    = peg$currPos * 59 + 58,
+          cached = peg$cache[key];
+
+      if (cached) {
+        peg$currPos = cached.nextPos;
+        return cached.result;
+      }
+
+      s0 = peg$currPos;
+      s1 = peg$parseassociationSend();
+      if (s1 !== peg$FAILED) {
+        s2 = [];
+        s3 = peg$parseassociationList();
+        while (s3 !== peg$FAILED) {
+          s2.push(s3);
+          s3 = peg$parseassociationList();
+        }
+        if (s2 !== peg$FAILED) {
+          peg$reportedPos = s0;
+          s1 = peg$c138(s1, s2);
+          s0 = s1;
+        } else {
+          peg$currPos = s0;
+          s0 = peg$c1;
+        }
+      } else {
+        peg$currPos = s0;
+        s0 = peg$c1;
+      }
+
+      peg$cache[key] = { nextPos: peg$currPos, result: s0 };
+
+      return s0;
+    }
+
     peg$result = peg$startRuleFunction();
 
     if (peg$result !== peg$FAILED && peg$currPos === input.length) {

+ 7 - 1
support/parser.pegjs

@@ -47,7 +47,7 @@ dynamicArray   = "{" ws expressions:expressions? ws "."? "}" {
                             ._source_(text())
                             ._nodes_(expressions || []);
                  }
-dynamicDictionary = "#{" ws expressions: expressions? ws "}" {
+dynamicDictionary = "#{" ws expressions: associations? ws "}" {
                         return globals.DynamicDictionaryNode._new()
                                ._position_((line()).__at(column()))
                                ._source_(text())
@@ -257,3 +257,9 @@ method         = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws s
                              ._nodes_([sequence]);
                  }
 
+
+associationSend     = send:binarySend & { return send._selector() === "->" } { return [send._receiver(), send._arguments()[0]]; }
+
+associationList = ws "." ws expression:associationSend {return expression;}
+associations    = first:associationSend others:associationList* { return first.concat.apply(first, others); }
+

Vissa filer visades inte eftersom för många filer har ändrats