Browse Source

recompiled

Herbert Vojčík 11 years ago
parent
commit
9dc768a835
4 changed files with 370 additions and 253 deletions
  1. 94 74
      lib/js/Trapped-Backend.js
  2. 93 54
      lib/js/Trapped-Demo.js
  3. 86 73
      lib/js/Trapped-Frontend.js
  4. 97 52
      lib/js/Trapped-Tests.js

+ 94 - 74
lib/js/Trapped-Backend.js

@@ -31,11 +31,12 @@ smalltalk.EavModel.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@getBlock"]=(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._error_("No getter block.");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+$ctx2.sendIdx["error:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})});
 self["@putBlock"]=(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._error_("No putter block.");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})});
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.EavModel)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09getBlock := [ self error: 'No getter block.' ].\x0a\x09putBlock := [ self error: 'No putter block.' ].",
@@ -188,7 +189,7 @@ smalltalk.Isolator.klass);
 
 
 smalltalk.addClass('KeyedPubSubBase', smalltalk.Object, ['factory'], 'Trapped-Backend');
-smalltalk.KeyedPubSubBase.comment="I represent a pub-sub based on a key.\x0aI manage key-block subscriptions as well as running blocks that are dirty.\x0aThe subscription objects are reponsible of decision if the change is relevant for them.\x0aSubscription object must be subclasses of KeyedSubscriptionBase.\x0a\x0aMy subclasses must provide implementation for:\x0a\x09add:\x0a    do:\x0a    clean\x0a    (optionally) run\x0a\x0aand issue this call before actual use:\x0a\x09subscritionFactory: (setting [:key:block|...] factory that creates appropriate subscription)";
+smalltalk.KeyedPubSubBase.comment="I represent a pub-sub based on a key.\x0d\x0aI manage key-block subscriptions as well as running blocks that are dirty.\x0d\x0aThe subscription objects are reponsible of decision if the change is relevant for them.\x0d\x0aSubscription object must be subclasses of KeyedSubscriptionBase.\x0d\x0a\x0d\x0aMy subclasses must provide implementation for:\x0d\x0a\x09add:\x0d\x0a    do:\x0d\x0a    clean\x0d\x0a    (optionally) run\x0d\x0a\x0d\x0aand issue this call before actual use:\x0d\x0a\x09subscritionFactory: (setting [:key:block|...] factory that creates appropriate subscription)";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "changed:",
@@ -207,12 +208,12 @@ _st(each)._flag();
 needsToRun=true;
 return needsToRun;
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 self._dirty_(needsToRun);
 return self}, function($ctx1) {$ctx1.fill(self,"changed:",{key:key,needsToRun:needsToRun},smalltalk.KeyedPubSubBase)})},
 args: ["key"],
 source: "changed: key\x0a\x09| needsToRun |\x0a    needsToRun := false.\x0a\x09self do: [ :each |\x0a\x09\x09(each accepts: key) ifTrue: [\x0a\x09\x09\x09each flag.\x0a            needsToRun := true.\x0a\x09\x09]\x0a\x09].\x0a\x09self dirty: needsToRun",
-messageSends: ["do:", "ifTrue:", "flag", "accepts:", "dirty:"],
+messageSends: ["do:", "ifTrue:", "accepts:", "flag", "dirty:"],
 referencedClasses: []
 }),
 smalltalk.KeyedPubSubBase);
@@ -224,13 +225,11 @@ category: 'action',
 fn: function (aBoolean){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=aBoolean;
-if(smalltalk.assert($1)){
+if(smalltalk.assert(aBoolean)){
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._run();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._fork();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}))._fork();
 };
 return self}, function($ctx1) {$ctx1.fill(self,"dirty:",{aBoolean:aBoolean},smalltalk.KeyedPubSubBase)})},
 args: ["aBoolean"],
@@ -282,19 +281,19 @@ if(! smalltalk.assert($2)){
 needsClean=true;
 return needsClean;
 };
-}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2)})}));
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)})}));
 $3=needsClean;
 if(smalltalk.assert($3)){
 return self._clean();
 };
-}, function($ctx2) {$ctx2.fillBlock({needsClean:needsClean},$ctx1)})}))._on_do_($Error(),(function(){
+}, function($ctx2) {$ctx2.fillBlock({needsClean:needsClean},$ctx1,1)})}))._on_do_($Error(),(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._dirty_(true);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,6)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"run",{},smalltalk.KeyedPubSubBase)})},
 args: [],
 source: "run\x0a\x09[\x0a\x09\x09| needsClean |\x0a\x09    needsClean := false.\x0a\x09\x09self do: [ :each |\x0a\x09\x09\x09each isFlagged ifTrue: [ each run ].\x0a\x09        each isEnabled ifFalse: [ needsClean := true ]\x0a\x09\x09].\x0a    \x09needsClean ifTrue: [ self clean ]\x0a\x09] on: Error do: [ self dirty: true ]",
-messageSends: ["on:do:", "dirty:", "do:", "ifTrue:", "run", "isFlagged", "ifFalse:", "isEnabled", "clean"],
+messageSends: ["on:do:", "do:", "ifTrue:", "isFlagged", "run", "ifFalse:", "isEnabled", "clean", "dirty:"],
 referencedClasses: ["Error"]
 }),
 smalltalk.KeyedPubSubBase);
@@ -344,7 +343,7 @@ return smalltalk.withContext(function($ctx1) {
 self["@queue"]=_st(self["@queue"])._select_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._isEnabled();
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"clean",{},smalltalk.SimpleKeyedPubSub)})},
 args: [],
 source: "clean\x0a\x09queue := queue select: [ :each | each isEnabled ]",
@@ -511,11 +510,11 @@ return smalltalk.withContext(function($ctx2) {
 self["@flagged"]=false;
 self["@flagged"];
 return _st(self["@actionBlock"])._value();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($KeyedPubSubUnsubscribe(),(function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($KeyedPubSubUnsubscribe(),(function(){
 return smalltalk.withContext(function($ctx2) {
 self["@actionBlock"]=nil;
 return self["@actionBlock"];
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"run",{},smalltalk.KeyedSubscriptionBase)})},
 args: [],
 source: "run\x0a\x09[ flagged := false. actionBlock value ]\x0a    on: KeyedPubSubUnsubscribe do: [ actionBlock := nil ]",
@@ -534,16 +533,21 @@ category: 'testing',
 fn: function (aKey){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(_st(aKey)._size()).__lt_eq(_st(self["@key"])._size()))._and_((function(){
+var $3,$4,$2,$1;
+$3=_st(aKey)._size();
+$ctx1.sendIdx["size"]=1;
+$4=_st(self["@key"])._size();
+$ctx1.sendIdx["size"]=2;
+$2=_st($3).__lt_eq($4);
+$1=_st($2)._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(aKey).__eq(_st(self["@key"])._copyFrom_to_((1),_st(aKey)._size()));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"accepts:",{aKey:aKey},smalltalk.ListKeyedSubscription)})},
 args: ["aKey"],
 source: "accepts: aKey\x0a    ^aKey size <= key size and: [aKey = (key copyFrom: 1 to: aKey size)]",
-messageSends: ["and:", "=", "copyFrom:to:", "size", "<="],
+messageSends: ["and:", "<=", "size", "=", "copyFrom:to:"],
 referencedClasses: []
 }),
 smalltalk.ListKeyedSubscription);
@@ -558,10 +562,20 @@ category: 'testing',
 fn: function (aKey){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=_st(_st(aKey)._size()).__lt_eq(_st(self["@key"])._size());
+var $3,$4,$2,$6,$7,$5,$1;
+$3=_st(aKey)._size();
+$ctx1.sendIdx["size"]=1;
+$4=_st(self["@key"])._size();
+$ctx1.sendIdx["size"]=2;
+$2=_st($3).__lt_eq($4);
 if(smalltalk.assert($2)){
-$1=_st(aKey).__eq(_st(self["@key"])._copyFrom_to_((1),_st(aKey)._size()));
+$6=self["@key"];
+$7=_st(aKey)._size();
+$ctx1.sendIdx["size"]=3;
+$5=_st($6)._copyFrom_to_((1),$7);
+$ctx1.sendIdx["copyFrom:to:"]=1;
+$1=_st(aKey).__eq($5);
+$ctx1.sendIdx["="]=1;
 } else {
 $1=_st(self["@key"]).__eq(_st(aKey)._copyFrom_to_((1),_st(self["@key"])._size()));
 };
@@ -569,7 +583,7 @@ return $1;
 }, function($ctx1) {$ctx1.fill(self,"accepts:",{aKey:aKey},smalltalk.TwoWayListKeyedSubscription)})},
 args: ["aKey"],
 source: "accepts: aKey\x0a    ^aKey size <= key size\x0a\x09\x09ifTrue: [aKey = (key copyFrom: 1 to: aKey size)]\x0a\x09\x09ifFalse: [key = (aKey copyFrom: 1 to: key size)]",
-messageSends: ["ifTrue:ifFalse:", "=", "copyFrom:to:", "size", "<="],
+messageSends: ["ifTrue:ifFalse:", "<=", "size", "=", "copyFrom:to:"],
 referencedClasses: []
 }),
 smalltalk.TwoWayListKeyedSubscription);
@@ -577,7 +591,7 @@ smalltalk.TwoWayListKeyedSubscription);
 
 
 smalltalk.addClass('ListKeyedEntity', smalltalk.Object, ['dispatcher', 'payload'], 'Trapped-Backend');
-smalltalk.ListKeyedEntity.comment="I am base class for #('string-at-index' #selector numeric-at-index)-array-path-keyed entities,\x0athat moderate access to the wrapped model object via read;do and modify:do:\x0aand allow pub-sub via watch:do:.\x0aThis wrapped model can be any smalltalk object.\x0a\x0aMy subclasses need to provide implementation for:\x0a\x09read:do:\x0a    modify:do:\x0a\x0aand must issue these calls when initializing:\x0a\x09model: (with a wrapped object)\x0a\x09dispatcher: (with a subclass of KeyedPubSubBase)";
+smalltalk.ListKeyedEntity.comment="I am base class for #('string-at-index' #selector numeric-at-index)-array-path-keyed entities,\x0d\x0athat moderate access to the wrapped model object via read;do and modify:do:\x0d\x0aand allow pub-sub via watch:do:.\x0d\x0aThis wrapped model can be any smalltalk object.\x0d\x0a\x0d\x0aMy subclasses need to provide implementation for:\x0d\x0a\x09read:do:\x0d\x0a    modify:do:\x0d\x0a\x0d\x0aand must issue these calls when initializing:\x0d\x0a\x09model: (with a wrapped object)\x0d\x0a\x09dispatcher: (with a subclass of KeyedPubSubBase)";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "dispatcher",
@@ -605,32 +619,35 @@ var self=this;
 function $TwoWayListKeyedSubscription(){return smalltalk.TwoWayListKeyedSubscription||(typeof TwoWayListKeyedSubscription=="undefined"?nil:TwoWayListKeyedSubscription)}
 function $ListKeyedSubscription(){return smalltalk.ListKeyedSubscription||(typeof ListKeyedSubscription=="undefined"?nil:ListKeyedSubscription)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4,$5,$6,$7;
-$1=aDispatcher;
-_st($1)._subscriptionFactory_((function(key,block){
+var $1,$2,$3,$4,$5,$6;
+_st(aDispatcher)._subscriptionFactory_((function(key,block){
 return smalltalk.withContext(function($ctx2) {
-$2=_st(_st(key)._notEmpty())._and_((function(){
+$1=_st(_st(key)._notEmpty())._and_((function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(_st(key)._last())._isNil();
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-if(smalltalk.assert($2)){
-$3=_st($TwoWayListKeyedSubscription())._new();
-_st($3)._key_block_(_st(key)._allButLast(),block);
-$4=_st($3)._yourself();
-return $4;
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+if(smalltalk.assert($1)){
+$2=_st($TwoWayListKeyedSubscription())._new();
+$ctx2.sendIdx["new"]=1;
+_st($2)._key_block_(_st(key)._allButLast(),block);
+$ctx2.sendIdx["key:block:"]=1;
+$3=_st($2)._yourself();
+$ctx2.sendIdx["yourself"]=1;
+return $3;
 } else {
-$5=_st($ListKeyedSubscription())._new();
-_st($5)._key_block_(key,block);
-$6=_st($5)._yourself();
-return $6;
+$4=_st($ListKeyedSubscription())._new();
+_st($4)._key_block_(key,block);
+$5=_st($4)._yourself();
+$ctx2.sendIdx["yourself"]=2;
+return $5;
 };
-}, function($ctx2) {$ctx2.fillBlock({key:key,block:block},$ctx1)})}));
-$7=_st($1)._yourself();
-self["@dispatcher"]=$7;
+}, function($ctx2) {$ctx2.fillBlock({key:key,block:block},$ctx1,1)})}));
+$6=_st(aDispatcher)._yourself();
+self["@dispatcher"]=$6;
 return self}, function($ctx1) {$ctx1.fill(self,"dispatcher:",{aDispatcher:aDispatcher},smalltalk.ListKeyedEntity)})},
 args: ["aDispatcher"],
 source: "dispatcher: aDispatcher\x0a\x09dispatcher := aDispatcher\x0a        subscriptionFactory: [ :key :block |\x0a\x09\x09\x09(key notEmpty and: [ key last isNil ])\x0a\x09\x09\x09\x09ifTrue: [ TwoWayListKeyedSubscription new key: key allButLast block: block; yourself ]\x0a\x09\x09\x09\x09ifFalse: [ ListKeyedSubscription new key: key block: block; yourself ]];\x0a        yourself",
-messageSends: ["subscriptionFactory:", "ifTrue:ifFalse:", "key:block:", "allButLast", "new", "yourself", "and:", "isNil", "last", "notEmpty"],
+messageSends: ["subscriptionFactory:", "ifTrue:ifFalse:", "and:", "notEmpty", "isNil", "last", "key:block:", "new", "allButLast", "yourself"],
 referencedClasses: ["TwoWayListKeyedSubscription", "ListKeyedSubscription"]
 }),
 smalltalk.ListKeyedEntity);
@@ -662,11 +679,11 @@ return smalltalk.withContext(function($ctx1) {
 _st(self._dispatcher())._on_hook_(path,(function(){
 return smalltalk.withContext(function($ctx2) {
 return self._read_do_(path,aBlock);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"watch:do:",{path:path,aBlock:aBlock},smalltalk.ListKeyedEntity)})},
 args: ["path", "aBlock"],
 source: "watch: path do: aBlock\x0a\x09self dispatcher on: path hook: [ self read: path do: aBlock ]",
-messageSends: ["on:hook:", "read:do:", "dispatcher"],
+messageSends: ["on:hook:", "dispatcher", "read:do:"],
 referencedClasses: []
 }),
 smalltalk.ListKeyedEntity);
@@ -674,7 +691,7 @@ smalltalk.ListKeyedEntity);
 
 
 smalltalk.addClass('ListKeyedDirectEntity', smalltalk.ListKeyedEntity, [], 'Trapped-Backend');
-smalltalk.ListKeyedDirectEntity.comment="I am ListKeyedEntity that directly manipulate\x0athe wrapped model object.";
+smalltalk.ListKeyedDirectEntity.comment="I am ListKeyedEntity that directly manipulate\x0d\x0athe wrapped model object.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "modify:do:",
@@ -688,14 +705,14 @@ newValue=_st(aBlock)._value_(_st(eavModel)._on_(self["@payload"]));
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(eavModel)._on_put_(self["@payload"],newValue);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._dispatcher())._changed_(path);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"modify:do:",{path:path,aBlock:aBlock,newValue:newValue,eavModel:eavModel},smalltalk.ListKeyedDirectEntity)})},
 args: ["path", "aBlock"],
 source: "modify: path do: aBlock\x0a    | newValue eavModel |\x0a    eavModel := path asEavModel.\x0a    newValue := aBlock value: (eavModel on: payload).\x0a    [ eavModel on: payload put: newValue ] ensure: [ self dispatcher changed: path ]",
-messageSends: ["asEavModel", "value:", "on:", "ensure:", "changed:", "dispatcher", "on:put:"],
+messageSends: ["asEavModel", "value:", "on:", "ensure:", "on:put:", "changed:", "dispatcher"],
 referencedClasses: []
 }),
 smalltalk.ListKeyedDirectEntity);
@@ -721,7 +738,7 @@ smalltalk.ListKeyedDirectEntity);
 
 
 smalltalk.addClass('ListKeyedIsolatedEntity', smalltalk.ListKeyedEntity, [], 'Trapped-Backend');
-smalltalk.ListKeyedIsolatedEntity.comment="I am ListKeyedEntity that guards access\x0ato the wrapped model object via Isolator.";
+smalltalk.ListKeyedIsolatedEntity.comment="I am ListKeyedEntity that guards access\x0d\x0ato the wrapped model object via Isolator.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "model:",
@@ -751,14 +768,14 @@ eavModel=_st(_st([["root"]]).__comma(path))._asEavModel();
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self["@payload"])._model_modify_(eavModel,aBlock);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._dispatcher())._changed_(path);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"modify:do:",{path:path,aBlock:aBlock,eavModel:eavModel},smalltalk.ListKeyedIsolatedEntity)})},
 args: ["path", "aBlock"],
 source: "modify: path do: aBlock\x0a    | eavModel |\x0a    eavModel := ({{#root}},path) asEavModel.\x0a    [ payload model: eavModel modify: aBlock ] ensure: [ self dispatcher changed: path ]",
-messageSends: ["asEavModel", ",", "ensure:", "changed:", "dispatcher", "model:modify:"],
+messageSends: ["asEavModel", ",", "ensure:", "model:modify:", "changed:", "dispatcher"],
 referencedClasses: []
 }),
 smalltalk.ListKeyedIsolatedEntity);
@@ -805,7 +822,10 @@ category: '*Trapped-Backend',
 fn: function (anObject,value){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._error_(_st("Trapped cannot put at ".__comma(_st(self._class())._name())).__comma(" type key."));
+var $1;
+$1=_st("Trapped cannot put at ".__comma(_st(self._class())._name())).__comma(" type key.");
+$ctx1.sendIdx[","]=1;
+self._error_($1);
 return self}, function($ctx1) {$ctx1.fill(self,"reverseTrapAt:put:",{anObject:anObject,value:value},smalltalk.Object)})},
 args: ["anObject", "value"],
 source: "reverseTrapAt: anObject put: value\x0a\x09self error: 'Trapped cannot put at ', self class name, ' type key.'",
@@ -825,7 +845,7 @@ var $1;
 $1=_st(anObject)._at_ifAbsent_(self,(function(){
 return smalltalk.withContext(function($ctx2) {
 return nil;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"reverseTrapAt:",{anObject:anObject},smalltalk.Number)})},
 args: ["anObject"],
@@ -862,44 +882,44 @@ var self=this;
 var model;
 function $EavModel(){return smalltalk.EavModel||(typeof EavModel=="undefined"?nil:EavModel)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
+var $1,$2;
 model=_st($EavModel())._new();
 _st(model)._getBlock_((function(anObject){
 return smalltalk.withContext(function($ctx2) {
 return self._inject_into_(anObject,(function(soFar,segment){
 return smalltalk.withContext(function($ctx3) {
-$1=soFar;
-if(($receiver = $1) == nil || $receiver == undefined){
-return $1;
+if(($receiver = soFar) == nil || $receiver == null){
+return soFar;
 } else {
 return _st(segment)._reverseTrapAt_(soFar);
+$ctx3.sendIdx["reverseTrapAt:"]=1;
 };
-}, function($ctx3) {$ctx3.fillBlock({soFar:soFar,segment:segment},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({anObject:anObject},$ctx1)})}));
-$2=self._isEmpty();
-if(! smalltalk.assert($2)){
+}, function($ctx3) {$ctx3.fillBlock({soFar:soFar,segment:segment},$ctx2,2)})}));
+$ctx2.sendIdx["inject:into:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({anObject:anObject},$ctx1,1)})}));
+$1=self._isEmpty();
+if(! smalltalk.assert($1)){
 _st(model)._putBlock_((function(anObject,value){
 var penultimate;
 return smalltalk.withContext(function($ctx2) {
 penultimate=_st(self._allButLast())._inject_into_(anObject,(function(soFar,segment){
 return smalltalk.withContext(function($ctx3) {
-$3=soFar;
-if(($receiver = $3) == nil || $receiver == undefined){
-return $3;
+if(($receiver = soFar) == nil || $receiver == null){
+return soFar;
 } else {
 return _st(segment)._reverseTrapAt_(soFar);
 };
-}, function($ctx3) {$ctx3.fillBlock({soFar:soFar,segment:segment},$ctx2)})}));
+}, function($ctx3) {$ctx3.fillBlock({soFar:soFar,segment:segment},$ctx2,6)})}));
 penultimate;
 return _st(self._last())._reverseTrapAt_put_(penultimate,value);
-}, function($ctx2) {$ctx2.fillBlock({anObject:anObject,value:value,penultimate:penultimate},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({anObject:anObject,value:value,penultimate:penultimate},$ctx1,5)})}));
 };
-$4=model;
-return $4;
+$2=model;
+return $2;
 }, function($ctx1) {$ctx1.fill(self,"asEavModel",{model:model},smalltalk.SequenceableCollection)})},
 args: [],
 source: "asEavModel\x0a    | model |\x0a    model := EavModel new.\x0a    model getBlock: [ :anObject |\x0a        self inject: anObject into: [ :soFar :segment |\x0a            soFar ifNotNil: [ segment reverseTrapAt: soFar ]]].\x0a    self isEmpty ifFalse: [\x0a        model putBlock: [ :anObject :value | | penultimate |\x0a            penultimate :=  self allButLast inject: anObject into: [ :soFar :segment |\x0a                soFar ifNotNil: [ segment reverseTrapAt: soFar ]].\x0a            self last reverseTrapAt: penultimate put: value ]].\x0a    ^model",
-messageSends: ["new", "getBlock:", "inject:into:", "ifNotNil:", "reverseTrapAt:", "ifFalse:", "putBlock:", "allButLast", "reverseTrapAt:put:", "last", "isEmpty"],
+messageSends: ["new", "getBlock:", "inject:into:", "ifNotNil:", "reverseTrapAt:", "ifFalse:", "isEmpty", "putBlock:", "allButLast", "reverseTrapAt:put:", "last"],
 referencedClasses: ["EavModel"]
 }),
 smalltalk.SequenceableCollection);
@@ -915,7 +935,7 @@ var $1;
 $1=_st(anObject)._at_ifAbsent_(self,(function(){
 return smalltalk.withContext(function($ctx2) {
 return nil;
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"reverseTrapAt:",{anObject:anObject},smalltalk.String)})},
 args: ["anObject"],
@@ -957,10 +977,10 @@ try {
 $1=_st((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(anObject)._perform_(self._first());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($MessageNotUnderstood(),(function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($MessageNotUnderstood(),(function(){
 return smalltalk.withContext(function($ctx2) {
 throw $early=[nil];
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 return $1;
 }
 catch(e) {if(e===$early)return e[0]; throw e}

+ 93 - 54
lib/js/Trapped-Demo.js

@@ -13,20 +13,31 @@ var self=this;
 function $SimpleKeyedPubSub(){return smalltalk.SimpleKeyedPubSub||(typeof SimpleKeyedPubSub=="undefined"?nil:SimpleKeyedPubSub)}
 function $AppModel(){return smalltalk.AppModel||(typeof AppModel=="undefined"?nil:AppModel)}
 return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$4,$2,$6,$5;
 smalltalk.App.superclass.fn.prototype._initialize.apply(_st(self), []);
-self._dispatcher_(_st($SimpleKeyedPubSub())._new());
+$1=_st($SimpleKeyedPubSub())._new();
+$ctx1.sendIdx["new"]=1;
+self._dispatcher_($1);
 self._model_(_st(_st($AppModel())._new())._title_("Todo"));
 self._watch_do_([["todos"], nil],(function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._dispatcher())._changed_([["remaining"]]);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._modify_do_([["todos"]],(function(){
 return smalltalk.withContext(function($ctx3) {
-return [smalltalk.HashedCollection._from_(["text".__minus_gt("learn trapped"),"done".__minus_gt(true)]),smalltalk.HashedCollection._from_(["text".__minus_gt("build a trapped app"),"done".__minus_gt(false)])];
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((2000));
+$3="text".__minus_gt("learn trapped");
+$ctx3.sendIdx["->"]=1;
+$4="done".__minus_gt(true);
+$ctx3.sendIdx["->"]=2;
+$2=smalltalk.HashedCollection._from_([$3,$4]);
+$6="text".__minus_gt("build a trapped app");
+$ctx3.sendIdx["->"]=3;
+$5=smalltalk.HashedCollection._from_([$6,"done".__minus_gt(false)]);
+return [$2,$5];
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,3)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}))._valueWithTimeout_((2000));
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.App)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a    self dispatcher: SimpleKeyedPubSub new.\x0a    self model: (AppModel new title: 'Todo').\x0a\x09self watch: #((todos) nil) do: [ self dispatcher changed: #((remaining)) ].\x0a    [ self modify: #((todos)) do: [{\x0a        #{'text'->'learn trapped'. 'done'->true}.\x0a        #{'text'->'build a trapped app'. 'done'->false}\x0a    }]] valueWithTimeout: 2000",
@@ -46,12 +57,17 @@ category: 'action',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self._todos())._add_(smalltalk.HashedCollection._from_(["text".__minus_gt(self._todoText()),"done".__minus_gt(false)]));
+var $1,$3,$2;
+$1=self._todos();
+$3="text".__minus_gt(self._todoText());
+$ctx1.sendIdx["->"]=1;
+$2=smalltalk.HashedCollection._from_([$3,"done".__minus_gt(false)]);
+_st($1)._add_($2);
 self._todoText_("");
 return self}, function($ctx1) {$ctx1.fill(self,"addTodo",{},smalltalk.AppModel)})},
 args: [],
 source: "addTodo\x0a    self todos add: #{'text'->self todoText. 'done'->false}.\x0a    self todoText: ''",
-messageSends: ["add:", "->", "todoText", "todos", "todoText:"],
+messageSends: ["add:", "todos", "->", "todoText", "todoText:"],
 referencedClasses: []
 }),
 smalltalk.AppModel);
@@ -203,12 +219,12 @@ var $1;
 $1=_st(self._todos())._reject_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._at_("done");
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"todosNotDone",{},smalltalk.AppModel)})},
 args: [],
 source: "todosNotDone\x0a    ^self todos reject: [ :each | each at: 'done' ]",
-messageSends: ["reject:", "at:", "todos"],
+messageSends: ["reject:", "todos", "at:"],
 referencedClasses: []
 }),
 smalltalk.AppModel);
@@ -224,83 +240,106 @@ category: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4,$5,$6,$7,$9,$10,$11,$12,$8;
+var $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$12,$13,$14,$15,$11;
 []._trapDescend_((function(snap){
 return smalltalk.withContext(function($ctx2) {
 _st(_st(html)._h2())._trap_([["title"]]);
+$ctx2.sendIdx["trap:"]=1;
 return _st(_st(html)._div())._trap_toggle_ifNotPresent_([["todos"]],(function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(snap)._do_((function(){
 return smalltalk.withContext(function($ctx4) {
-_st(_st(html)._span())._trap_([["remaining"]]);
+$1=_st(html)._span();
+$ctx4.sendIdx["span"]=1;
+_st($1)._trap_([["remaining"]]);
+$ctx4.sendIdx["trap:"]=2;
 _st(html)._with_(" of ");
-_st(_st(html)._span())._trap_([["todos"], ["size"]]);
+$ctx4.sendIdx["with:"]=1;
+$2=_st(html)._span();
+$ctx4.sendIdx["span"]=2;
+_st($2)._trap_([["todos"], ["size"]]);
+$ctx4.sendIdx["trap:"]=3;
 _st(html)._with_(" remaining [ ");
-$1=_st(html)._a();
-_st($1)._href_("");
-_st($1)._onClick_((function(){
+$ctx4.sendIdx["with:"]=2;
+$3=_st(html)._a();
+_st($3)._href_("");
+_st($3)._onClick_((function(){
 return smalltalk.withContext(function($ctx5) {
 _st(snap)._modify_((function(model){
 return smalltalk.withContext(function($ctx6) {
 return _st(model)._archive();
-}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx5)})}));
+}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx5,5)})}));
+$ctx5.sendIdx["modify:"]=1;
 return false;
-}, function($ctx5) {$ctx5.fillBlock({},$ctx4)})}));
-$2=_st($1)._with_("archive");
-$2;
+}, function($ctx5) {$ctx5.fillBlock({},$ctx4,4)})}));
+$4=_st($3)._with_("archive");
+$ctx4.sendIdx["with:"]=3;
+$4;
 _st(html)._with_(" ]");
+$ctx4.sendIdx["with:"]=4;
 _st(_st(html)._ul())._with_((function(){
 return smalltalk.withContext(function($ctx5) {
 return _st(html)._trapIter_tag_do_([["todos"]],"li",(function(each){
 return smalltalk.withContext(function($ctx6) {
-_st(_st(html)._root())._empty();
-$3=_st(html)._input();
-_st($3)._type_("checkbox");
-$4=_st($3)._trap_(["done"]);
-$4;
-$5=_st(html)._span();
-_st($5)._trap_read_(["done"],(function(model){
+$5=_st(html)._root();
+$ctx6.sendIdx["root"]=1;
+_st($5)._empty();
+$6=_st(html)._input();
+$ctx6.sendIdx["input"]=1;
+_st($6)._type_("checkbox");
+$ctx6.sendIdx["type:"]=1;
+$7=_st($6)._trap_(["done"]);
+$ctx6.sendIdx["trap:"]=4;
+$7;
+$8=_st(html)._span();
+_st($8)._trap_read_(["done"],(function(model){
 return smalltalk.withContext(function($ctx7) {
 return _st(_st(html)._root())._class_("done-".__comma(model));
-}, function($ctx7) {$ctx7.fillBlock({model:model},$ctx6)})}));
-$6=_st($5)._trap_(["text"]);
-return $6;
-}, function($ctx6) {$ctx6.fillBlock({each:each},$ctx5)})}));
-}, function($ctx5) {$ctx5.fillBlock({},$ctx4)})}));
-$7=_st(html)._form();
-_st($7)._onSubmit_((function(){
+$ctx7.sendIdx["class:"]=1;
+}, function($ctx7) {$ctx7.fillBlock({model:model},$ctx6,8)})}));
+$9=_st($8)._trap_(["text"]);
+$ctx6.sendIdx["trap:"]=5;
+return $9;
+}, function($ctx6) {$ctx6.fillBlock({each:each},$ctx5,7)})}));
+}, function($ctx5) {$ctx5.fillBlock({},$ctx4,6)})}));
+$ctx4.sendIdx["with:"]=5;
+$10=_st(html)._form();
+_st($10)._onSubmit_((function(){
 return smalltalk.withContext(function($ctx5) {
 _st(snap)._modify_((function(model){
 return smalltalk.withContext(function($ctx6) {
 return _st(model)._addTodo();
-}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx5)})}));
+}, function($ctx6) {$ctx6.fillBlock({model:model},$ctx5,10)})}));
 return false;
-}, function($ctx5) {$ctx5.fillBlock({},$ctx4)})}));
-$8=_st($7)._with_((function(){
+}, function($ctx5) {$ctx5.fillBlock({},$ctx4,9)})}));
+$11=_st($10)._with_((function(){
 return smalltalk.withContext(function($ctx5) {
-$9=_st(html)._input();
-_st($9)._type_("text");
-_st($9)._trap_([["todoText"]]);
-_st($9)._at_put_("size",(30));
-$10=_st($9)._placeholder_("add new todo here");
-$10;
-$11=_st(html)._input();
-_st($11)._class_("btn-primary");
-_st($11)._type_("submit");
-$12=_st($11)._value_("add");
-return $12;
-}, function($ctx5) {$ctx5.fillBlock({},$ctx4)})}));
-return $8;
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}));
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}),(function(){
+$12=_st(html)._input();
+$ctx5.sendIdx["input"]=2;
+_st($12)._type_("text");
+$ctx5.sendIdx["type:"]=2;
+_st($12)._trap_([["todoText"]]);
+_st($12)._at_put_("size",(30));
+$13=_st($12)._placeholder_("add new todo here");
+$13;
+$14=_st(html)._input();
+_st($14)._class_("btn-primary");
+_st($14)._type_("submit");
+$15=_st($14)._value_("add");
+return $15;
+}, function($ctx5) {$ctx5.fillBlock({},$ctx4,11)})}));
+$ctx4.sendIdx["with:"]=6;
+return $11;
+}, function($ctx4) {$ctx4.fillBlock({},$ctx3,3)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}),(function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(html)._with_("Loading ...");
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,12)})}));
+}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.AppView)})},
 args: ["html"],
 source: "renderOn: html\x0a    #() trapDescend: [ :snap |\x0a\x09html h2 trap: #((title)).\x0a    html div trap: #((todos)) toggle: [ snap do: [\x0a        html span trap:#((remaining)).\x0a        html with: ' of '.\x0a        html span trap: #((todos) (size)).\x0a        html with: ' remaining [ '.\x0a        html a href:''; onClick: [\x0a            snap modify: [ :model | model archive ].\x0a            false\x0a        ]; with: 'archive'.\x0a        html with: ' ]'.\x0a        html ul with: [ html trapIter: #((todos)) tag: #li do: [ :each |\x0a            html root empty.\x0a            html input type: 'checkbox'; trap: #('done').\x0a            html span trap: #('done') read: [ :model | html root class: 'done-', model ]; trap: #('text').\x0a        ]].\x0a        html form onSubmit: [\x0a            snap modify: [ :model | model addTodo ].\x0a            false\x0a        ]; with: [\x0a            html input type: 'text'; trap: #((todoText)); at: 'size' put: 30; placeholder: 'add new todo here'.\x0a            html input class: 'btn-primary'; type: 'submit'; value: 'add'.\x0a        ].\x0a    ]] ifNotPresent: [ html with: 'Loading ...' ]]",
-messageSends: ["trapDescend:", "trap:", "h2", "trap:toggle:ifNotPresent:", "do:", "span", "with:", "href:", "a", "onClick:", "modify:", "archive", "trapIter:tag:do:", "empty", "root", "type:", "input", "trap:read:", "class:", ",", "ul", "onSubmit:", "addTodo", "form", "at:put:", "placeholder:", "value:", "div"],
+messageSends: ["trapDescend:", "trap:", "h2", "trap:toggle:ifNotPresent:", "div", "do:", "span", "with:", "href:", "a", "onClick:", "modify:", "archive", "ul", "trapIter:tag:do:", "empty", "root", "type:", "input", "trap:read:", "class:", ",", "onSubmit:", "form", "addTodo", "at:put:", "placeholder:", "value:"],
 referencedClasses: []
 }),
 smalltalk.AppView);

+ 86 - 73
lib/js/Trapped-Frontend.js

@@ -58,23 +58,22 @@ category: 'action',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$4,$6,$5,$3,$1;
+var $2,$4,$5,$3,$1;
 $1=(function(model){
 return smalltalk.withContext(function($ctx2) {
 $2=self["@brush"];
 _st($2)._empty();
 $4=$2;
-$6=model;
-if(($receiver = $6) == nil || $receiver == undefined){
+if(($receiver = model) == nil || $receiver == null){
 $5=(function(){
 return smalltalk.withContext(function($ctx3) {
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})});
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,3)})});
 } else {
-$5=$6;
+$5=model;
 };
 $3=_st($4)._with_($5);
 return $3;
-}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})});
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1,1)})});
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"showBlock",{},smalltalk.TrappedBinder)})},
 args: [],
@@ -102,9 +101,9 @@ return smalltalk.withContext(function($ctx3) {
 return _st(snap)._modify_((function(){
 return smalltalk.withContext(function($ctx4) {
 return _st(_st(_st(self["@brush"])._asJQuery())._attr_("checked"))._notNil();
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}));
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1)})}));
+}, function($ctx4) {$ctx4.fillBlock({},$ctx3,3)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"installFor:",{path:path},smalltalk.TrappedCheckedBinder)})},
 args: ["path"],
 source: "installFor: path\x0a\x09super installFor: path.\x0a    path trapDescend: [ :snap |\x0a\x09    brush onChange: [ snap modify: [\x0a            (brush asJQuery attr: 'checked') notNil\x0a        ]]\x0a    ]",
@@ -120,23 +119,22 @@ category: 'action',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$4,$3,$1;
+var $2,$3,$1;
 $1=(function(model){
 return smalltalk.withContext(function($ctx2) {
 $2=_st(self["@brush"])._asJQuery();
-$4=model;
-if(($receiver = $4) == nil || $receiver == undefined){
+if(($receiver = model) == nil || $receiver == null){
 $3=false;
 } else {
 $3=self._prim_(model);
 };
 return _st($2)._attr_put_("checked",$3);
-}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})});
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1,1)})});
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"showBlock",{},smalltalk.TrappedCheckedBinder)})},
 args: [],
 source: "showBlock\x0a\x09^[ :model | brush asJQuery attr: 'checked' put: (model ifNotNil: [ self prim: model ] ifNil: [ false ]) ]",
-messageSends: ["attr:put:", "ifNotNil:ifNil:", "prim:", "asJQuery"],
+messageSends: ["attr:put:", "asJQuery", "ifNotNil:ifNil:", "prim:"],
 referencedClasses: []
 }),
 smalltalk.TrappedCheckedBinder);
@@ -159,9 +157,9 @@ return smalltalk.withContext(function($ctx3) {
 return _st(snap)._modify_((function(){
 return smalltalk.withContext(function($ctx4) {
 return _st(_st(self["@brush"])._asJQuery())._val();
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}));
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1)})}));
+}, function($ctx4) {$ctx4.fillBlock({},$ctx3,3)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"installFor:",{path:path},smalltalk.TrappedValBinder)})},
 args: ["path"],
 source: "installFor: path\x0a\x09super installFor: path.\x0a    path trapDescend: [ :snap |\x0a\x09    brush onChange: [ snap modify: [\x0a            brush asJQuery val\x0a        ]]\x0a    ]",
@@ -177,25 +175,24 @@ category: 'action',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$4,$3,$1;
+var $2,$3,$1;
 $1=(function(model){
 return smalltalk.withContext(function($ctx2) {
 $2=_st(self["@brush"])._asJQuery();
-$4=model;
-if(($receiver = $4) == nil || $receiver == undefined){
+if(($receiver = model) == nil || $receiver == null){
 $3=(function(){
 return smalltalk.withContext(function($ctx3) {
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})});
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,4)})});
 } else {
 $3=self._prim_(model);
 };
 return _st($2)._val_($3);
-}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})});
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1,1)})});
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"showBlock",{},smalltalk.TrappedValBinder)})},
 args: [],
 source: "showBlock\x0a\x09^[ :model | brush asJQuery val: (model ifNotNil: [self prim: model] ifNil: [[]]) ]",
-messageSends: ["val:", "ifNotNil:ifNil:", "prim:", "asJQuery"],
+messageSends: ["val:", "asJQuery", "ifNotNil:ifNil:", "prim:"],
 referencedClasses: []
 }),
 smalltalk.TrappedValBinder);
@@ -252,7 +249,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
 $2=self["@current"];
-if(($receiver = $2) == nil || $receiver == undefined){
+if(($receiver = $2) == nil || $receiver == null){
 self["@current"]=self._new();
 $1=self["@current"];
 } else {
@@ -299,23 +296,27 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3,$4,$6,$7,$5;
 tag=_st(_st(aTagBrush)._element())._nodeName();
 $1=_st(tag).__eq("INPUT");
+$ctx1.sendIdx["="]=1;
 if(smalltalk.assert($1)){
 var type;
 type=_st(_st(aTagBrush)._asJQuery())._attr_("type");
 type;
 $2=_st(type).__eq("checkbox");
+$ctx1.sendIdx["="]=2;
 if(smalltalk.assert($2)){
 binder=_st($TrappedCheckedBinder())._new();
+$ctx1.sendIdx["new"]=1;
 binder;
 };
 $3=_st(type).__eq("text");
 if(smalltalk.assert($3)){
 binder=_st($TrappedValBinder())._new();
+$ctx1.sendIdx["new"]=2;
 binder;
 };
 };
 $4=binder;
-if(($receiver = $4) == nil || $receiver == undefined){
+if(($receiver = $4) == nil || $receiver == null){
 binder=_st($TrappedBinder())._new();
 binder;
 } else {
@@ -329,7 +330,7 @@ return $5;
 }, function($ctx1) {$ctx1.fill(self,"binder:",{aTagBrush:aTagBrush,binder:binder,tag:tag},smalltalk.Trapped)})},
 args: ["aTagBrush"],
 source: "binder: aTagBrush\x0a    \x22Prototype; will select based on tag etc.\x22\x0a    | binder tag |\x0a    tag := aTagBrush element nodeName.\x0a    tag = 'INPUT' ifTrue: [\x0a        | type |\x0a        type := aTagBrush asJQuery attr: 'type'.\x0a        type = 'checkbox' ifTrue: [ binder := TrappedCheckedBinder new ].\x0a        type = 'text' ifTrue: [ binder := TrappedValBinder new ]\x0a    ].\x0a    binder ifNil: [ binder := TrappedBinder new ].\x0a    ^ binder brush: aTagBrush; yourself",
-messageSends: ["nodeName", "element", "ifTrue:", "attr:", "asJQuery", "new", "=", "ifNil:", "brush:", "yourself"],
+messageSends: ["nodeName", "element", "ifTrue:", "=", "attr:", "asJQuery", "new", "ifNil:", "brush:", "yourself"],
 referencedClasses: ["TrappedCheckedBinder", "TrappedValBinder", "TrappedBinder"]
 }),
 smalltalk.Trapped);
@@ -371,7 +372,7 @@ path;
 model=self._byName_(_st(path)._first());
 model;
 return _st(aBlock)._value_(_st(_st($TrappedSnapshot())._new())._path_model_(path,model));
-}, function($ctx2) {$ctx2.fillBlock({path:path,model:model},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({path:path,model:model},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"descend:snapshotDo:",{anArray:anArray,aBlock:aBlock,tpsc:tpsc},smalltalk.Trapped)})},
 args: ["anArray", "aBlock"],
 source: "descend: anArray snapshotDo: aBlock\x0a\x09| tpsc |\x0a    tpsc := TrappedPathStack current.\x0a    tpsc append: anArray do: [\x0a        | path model |\x0a        path := tpsc elements copy.\x0a   \x09    model := self byName: path first.\x0a        aBlock value: (TrappedSnapshot new path: path model: model)\x0a    ]",
@@ -438,12 +439,14 @@ var self=this;
 function $Trapped(){return smalltalk.Trapped||(typeof Trapped=="undefined"?nil:Trapped)}
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $1,$2;
 _st(args)._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._register_(each);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
-_st("[data-trap]"._asJQuery())._each_((function(index,elem){
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+$1="[data-trap]"._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+_st($1)._each_((function(index,elem){
 var trap,jq,viewName,modelName,tokens,path;
 return smalltalk.withContext(function($ctx2) {
 jq=_st(elem)._asJQuery();
@@ -451,18 +454,21 @@ jq;
 trap=_st(jq)._attr_("data-trap");
 trap;
 tokens=_st(trap)._tokenize_(":");
+$ctx2.sendIdx["tokenize:"]=1;
 tokens;
-$1=_st(_st(tokens)._size()).__eq((1));
-if(smalltalk.assert($1)){
+$2=_st(_st(tokens)._size()).__eq((1));
+if(smalltalk.assert($2)){
 tokens=_st(["TrappedDumbView"]).__comma(tokens);
+$ctx2.sendIdx[","]=1;
 tokens;
 };
 viewName=_st(tokens)._first();
+$ctx2.sendIdx["first"]=1;
 viewName;
 tokens=_st(_st(_st(tokens)._second())._tokenize_(" "))._select_((function(each){
 return smalltalk.withContext(function($ctx3) {
 return _st(each)._notEmpty();
-}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2)})}));
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,4)})}));
 tokens;
 modelName=_st(tokens)._first();
 modelName;
@@ -471,12 +477,12 @@ path;
 return _st(_st([modelName]).__comma(path))._trapDescend_((function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(_st(_st(_st($Smalltalk())._current())._at_(viewName))._new())._appendToJQuery_(jq);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({index:index,elem:elem,trap:trap,jq:jq,viewName:viewName,modelName:modelName,tokens:tokens,path:path},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx2,5)})}));
+}, function($ctx2) {$ctx2.fillBlock({index:index,elem:elem,trap:trap,jq:jq,viewName:viewName,modelName:modelName,tokens:tokens,path:path},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"start:",{args:args},smalltalk.Trapped)})},
 args: ["args"],
 source: "start: args\x0a    args do: [ :each | self register: each ].\x0a\x09'[data-trap]' asJQuery each: [ :index :elem |\x0a    \x09| trap jq viewName modelName tokens path |\x0a        jq := elem asJQuery.\x0a        trap := jq attr: 'data-trap'.\x0a        tokens := trap tokenize: ':'.\x0a        tokens size = 1 ifTrue: [ tokens := { 'TrappedDumbView' }, tokens ].\x0a        viewName := tokens first.\x0a        tokens := (tokens second tokenize: ' ') select: [ :each | each notEmpty ].\x0a        modelName := tokens first.\x0a        path := Trapped parse: tokens allButFirst.\x0a        { modelName }, path trapDescend: [(Smalltalk current at: viewName) new appendToJQuery: jq].\x0a    ]",
-messageSends: ["do:", "register:", "each:", "asJQuery", "attr:", "tokenize:", "ifTrue:", ",", "=", "size", "first", "select:", "notEmpty", "second", "parse:", "allButFirst", "trapDescend:", "appendToJQuery:", "new", "at:", "current"],
+messageSends: ["do:", "register:", "each:", "asJQuery", "attr:", "tokenize:", "ifTrue:", "=", "size", ",", "first", "select:", "second", "notEmpty", "parse:", "allButFirst", "trapDescend:", "appendToJQuery:", "new", "at:", "current"],
 referencedClasses: ["Trapped", "Smalltalk"]
 }),
 smalltalk.Trapped);
@@ -496,9 +502,9 @@ return smalltalk.withContext(function($ctx2) {
 _st(envelope)._with_((function(html){
 return smalltalk.withContext(function($ctx3) {
 return _st(_st(html)._perform_(aSymbol))._trap_read_([i],aBlock);
-}, function($ctx3) {$ctx3.fillBlock({html:html},$ctx2)})}));
+}, function($ctx3) {$ctx3.fillBlock({html:html},$ctx2,2)})}));
 return _st(_st(_st(envjq)._children())._detach())._insertBefore_(endjq);
-}, function($ctx2) {$ctx2.fillBlock({item:item,i:i},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({item:item,i:i},$ctx1,1)})}));
 _st(envjq)._remove();
 return self}, function($ctx1) {$ctx1.fill(self,"envelope:loop:before:tag:do:",{envelope:envelope,model:model,endjq:endjq,aSymbol:aSymbol,aBlock:aBlock,envjq:envjq},smalltalk.Trapped.klass)})},
 args: ["envelope", "model", "endjq", "aSymbol", "aBlock"],
@@ -515,21 +521,23 @@ category: 'private',
 fn: function (model,start,end,aSymbol,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-_st(_st(_st(start)._asJQuery())._nextUntil_(_st(end)._element()))._remove();
+var $2,$1;
+$2=_st(start)._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+$1=_st($2)._nextUntil_(_st(end)._element());
+_st($1)._remove();
 _st(start)._with_((function(html){
 return smalltalk.withContext(function($ctx2) {
-$1=model;
-if(($receiver = $1) == nil || $receiver == undefined){
-return $1;
+if(($receiver = model) == nil || $receiver == null){
+return model;
 } else {
 return self._envelope_loop_before_tag_do_(_st(html)._div(),model,_st(end)._asJQuery(),aSymbol,aBlock);
 };
-}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"loop:between:and:tag:do:",{model:model,start:start,end:end,aSymbol:aSymbol,aBlock:aBlock},smalltalk.Trapped.klass)})},
 args: ["model", "start", "end", "aSymbol", "aBlock"],
 source: "loop: model between: start and: end tag: aSymbol do: aBlock\x0a    (start asJQuery nextUntil: end element) remove.\x0a    start with: [ :html | model ifNotNil: [\x0a    \x09self envelope: html div loop: model before: end asJQuery tag: aSymbol do: aBlock\x0a\x09]]",
-messageSends: ["remove", "nextUntil:", "element", "asJQuery", "with:", "ifNotNil:", "envelope:loop:before:tag:do:", "div"],
+messageSends: ["remove", "nextUntil:", "asJQuery", "element", "with:", "ifNotNil:", "envelope:loop:before:tag:do:", "div"],
 referencedClasses: []
 }),
 smalltalk.Trapped.klass);
@@ -548,6 +556,7 @@ return smalltalk.withContext(function($ctx2) {
 asNum=_st(each)._asNumber();
 asNum;
 $2=_st(asNum).__eq(asNum);
+$ctx2.sendIdx["="]=1;
 if(smalltalk.assert($2)){
 return asNum;
 } else {
@@ -558,12 +567,12 @@ return [_st(each)._allButFirst()];
 return each;
 };
 };
-}, function($ctx2) {$ctx2.fillBlock({each:each,asNum:asNum},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each,asNum:asNum},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"parse:",{anArray:anArray},smalltalk.Trapped.klass)})},
 args: ["anArray"],
 source: "parse: anArray\x0a\x09^anArray collect: [ :each |\x0a    \x09| asNum |\x0a       \x09asNum := each asNumber.\x0a        asNum = asNum ifTrue: [ asNum ] ifFalse: [\x0a\x09\x09\x09each first = '#' ifTrue: [ { each allButFirst } ] ifFalse: [ each ]]]",
-messageSends: ["collect:", "asNumber", "ifTrue:ifFalse:", "allButFirst", "=", "first"],
+messageSends: ["collect:", "asNumber", "ifTrue:ifFalse:", "=", "first", "allButFirst"],
 referencedClasses: []
 }),
 smalltalk.Trapped.klass);
@@ -635,11 +644,11 @@ return smalltalk.withContext(function($ctx2) {
 self["@elements"]=anArray;
 self["@elements"];
 return _st(aBlock)._value();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx2) {
 self["@elements"]=old;
 return self["@elements"];
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"with:do:",{anArray:anArray,aBlock:aBlock,old:old},smalltalk.TrappedPathStack)})},
 args: ["anArray", "aBlock"],
 source: "with: anArray do: aBlock\x0a\x09| old |\x0a    old := elements.\x0a    [ elements := anArray.\x0a\x09aBlock value ] ensure: [ elements := old ]",
@@ -662,11 +671,11 @@ return smalltalk.withContext(function($ctx1) {
 _st(_st($TrappedPathStack())._current())._with_do_(self["@path"],(function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(aBlock)._value_(self["@model"]);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"do:",{aBlock:aBlock},smalltalk.TrappedSnapshot)})},
 args: ["aBlock"],
 source: "do: aBlock\x0a\x09TrappedPathStack current with: path do: [ aBlock value: model ]",
-messageSends: ["with:do:", "value:", "current"],
+messageSends: ["with:do:", "current", "value:"],
 referencedClasses: ["TrappedPathStack"]
 }),
 smalltalk.TrappedSnapshot);
@@ -700,7 +709,7 @@ _st(self._model())._modify_do_(_st(self._path())._allButFirst(),aBlock);
 return self}, function($ctx1) {$ctx1.fill(self,"modify:",{aBlock:aBlock},smalltalk.TrappedSnapshot)})},
 args: ["aBlock"],
 source: "modify: aBlock\x0a\x09self model modify: self path allButFirst do: aBlock",
-messageSends: ["modify:do:", "allButFirst", "path", "model"],
+messageSends: ["modify:do:", "model", "allButFirst", "path"],
 referencedClasses: []
 }),
 smalltalk.TrappedSnapshot);
@@ -770,14 +779,15 @@ return smalltalk.withContext(function($ctx1) {
 self._with_((function(html){
 return smalltalk.withContext(function($ctx2) {
 start=_st(html)._script();
+$ctx2.sendIdx["script"]=1;
 start;
 end=_st(html)._script();
 return end;
-}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
 _st(start)._trap_read_(path,(function(model){
 return smalltalk.withContext(function($ctx2) {
 return _st($Trapped())._loop_between_and_tag_do_(model,start,end,aSymbol,aBlock);
-}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({model:model},$ctx1,2)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"trapIter:tag:do:",{path:path,aSymbol:aSymbol,aBlock:aBlock,start:start,end:end},smalltalk.HTMLCanvas)})},
 args: ["path", "aSymbol", "aBlock"],
 source: "trapIter: path tag: aSymbol do: aBlock\x0a\x09| start end |\x0a    self with: [ :html | start := html script. end := html script ].\x0a    start trap: path read: [ :model |\x0a    \x09Trapped loop: model between: start and: end tag: aSymbol do: aBlock.\x0a    ]",
@@ -825,14 +835,14 @@ return smalltalk.withContext(function($ctx4) {
 return self._with_((function(html){
 return smalltalk.withContext(function($ctx5) {
 return _st(aBlock)._value_value_(data,html);
-}, function($ctx5) {$ctx5.fillBlock({html:html},$ctx4)})}));
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}));
-}, function($ctx3) {$ctx3.fillBlock({data:data},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1)})}));
+}, function($ctx5) {$ctx5.fillBlock({html:html},$ctx4,5)})}));
+}, function($ctx4) {$ctx4.fillBlock({},$ctx3,4)})}));
+}, function($ctx3) {$ctx3.fillBlock({data:data},$ctx2,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({snap:snap},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"trap:read:",{path:path,aBlock:aBlock},smalltalk.TagBrush)})},
 args: ["path", "aBlock"],
 source: "trap: path read: aBlock\x0a\x09path trapDescend: [ :snap |\x0a        snap model watch: snap path allButFirst do: [ :data |\x0a            (self asJQuery closest: 'html') toArray isEmpty ifTrue: [ KeyedPubSubUnsubscribe signal ].\x0a        \x09snap do: [ self with: [ :html | aBlock value: data value: html ] ]\x0a    \x09]\x0a    ]",
-messageSends: ["trapDescend:", "watch:do:", "allButFirst", "path", "ifTrue:", "signal", "isEmpty", "toArray", "closest:", "asJQuery", "do:", "with:", "value:value:", "model"],
+messageSends: ["trapDescend:", "watch:do:", "model", "allButFirst", "path", "ifTrue:", "isEmpty", "toArray", "closest:", "asJQuery", "signal", "do:", "with:", "value:value:"],
 referencedClasses: ["KeyedPubSubUnsubscribe"]
 }),
 smalltalk.TagBrush);
@@ -847,7 +857,7 @@ return smalltalk.withContext(function($ctx1) {
 self._trap_toggle_ifNotPresent_(path,aBlock,(function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._asJQuery())._hide();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"trap:toggle:",{path:path,aBlock:aBlock},smalltalk.TagBrush)})},
 args: ["path", "aBlock"],
 source: "trap: path toggle: aBlock\x0a    self trap: path toggle: aBlock ifNotPresent: [ self asJQuery hide ]",
@@ -864,31 +874,34 @@ fn: function (path,aBlock,anotherBlock){
 var self=this;
 var shown;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$5,$4;
+var $2,$3,$1,$4,$5,$7,$6;
 shown=nil;
 self._trap_read_(path,(function(data,html){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(shown).__eq(_st(data)._notNil());
+$2=shown;
+$3=_st(data)._notNil();
+$ctx2.sendIdx["notNil"]=1;
+$1=_st($2).__eq($3);
 if(! smalltalk.assert($1)){
 shown=_st(data)._notNil();
 shown;
-$2=self._asJQuery();
-_st($2)._empty();
-$3=_st($2)._show();
-$3;
-$5=shown;
-if(smalltalk.assert($5)){
-$4=aBlock;
+$4=self._asJQuery();
+_st($4)._empty();
+$5=_st($4)._show();
+$5;
+$7=shown;
+if(smalltalk.assert($7)){
+$6=aBlock;
 } else {
-$4=anotherBlock;
+$6=anotherBlock;
 };
-return _st($4)._value_value_(data,html);
+return _st($6)._value_value_(data,html);
 };
-}, function($ctx2) {$ctx2.fillBlock({data:data,html:html},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({data:data,html:html},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"trap:toggle:ifNotPresent:",{path:path,aBlock:aBlock,anotherBlock:anotherBlock,shown:shown},smalltalk.TagBrush)})},
 args: ["path", "aBlock", "anotherBlock"],
 source: "trap: path toggle: aBlock ifNotPresent: anotherBlock\x0a    | shown |\x0a    shown := nil.\x0a    self trap: path read: [ :data : html |\x0a        shown = data notNil ifFalse: [\x0a            shown := data notNil.\x0a            self asJQuery empty; show.\x0a            (shown ifTrue: [aBlock] ifFalse: [anotherBlock]) value: data value: html.\x0a        ]\x0a    ]",
-messageSends: ["trap:read:", "ifFalse:", "notNil", "empty", "asJQuery", "show", "value:value:", "ifTrue:ifFalse:", "="],
+messageSends: ["trap:read:", "ifFalse:", "=", "notNil", "empty", "asJQuery", "show", "value:value:", "ifTrue:ifFalse:"],
 referencedClasses: []
 }),
 smalltalk.TagBrush);

+ 97 - 52
lib/js/Trapped-Tests.js

@@ -16,16 +16,16 @@ $1=_st($EavModel())._new();
 _st($1)._getBlock_((function(x){
 return smalltalk.withContext(function($ctx2) {
 return _st(x)._root();
-}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)})}));
 $2=_st($1)._putBlock_((function(x,y){
 return smalltalk.withContext(function($ctx2) {
 return _st(x)._root_(y);
-}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)})}));
 self["@rootModel"]=$2;
 return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.IsolatorTest)})},
 args: [],
 source: "setUp\x0a\x0arootModel := EavModel new\x0a\x09getBlock: [:x | x root];\x0a    putBlock: [:x :y | x root: y].",
-messageSends: ["getBlock:", "root", "new", "putBlock:", "root:"],
+messageSends: ["getBlock:", "new", "root", "putBlock:", "root:"],
 referencedClasses: ["EavModel"]
 }),
 smalltalk.IsolatorTest);
@@ -40,29 +40,37 @@ var isolator,model,result;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 function $EavModel(){return smalltalk.EavModel||(typeof EavModel=="undefined"?nil:EavModel)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $2,$1,$3,$5,$4,$6;
 result=nil;
-isolator=_st($Isolator())._on_(smalltalk.HashedCollection._from_(["foo".__minus_gt(["bar", [(1), [(2), (5)]], "baz"]),"moo".__minus_gt("zoo")]));
-$1=_st($EavModel())._new();
-_st($1)._getBlock_((function(x){
+$2="foo".__minus_gt(["bar", [(1), [(2), (5)]], "baz"]);
+$ctx1.sendIdx["->"]=1;
+$1=smalltalk.HashedCollection._from_([$2,"moo".__minus_gt("zoo")]);
+isolator=_st($Isolator())._on_($1);
+$3=_st($EavModel())._new();
+_st($3)._getBlock_((function(x){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(_st(x)._root())._at_("foo"))._at_((2));
-}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})}));
-$2=_st($1)._putBlock_((function(x,y){
+$5=_st(x)._root();
+$ctx2.sendIdx["root"]=1;
+$4=_st($5)._at_("foo");
+$ctx2.sendIdx["at:"]=2;
+return _st($4)._at_((2));
+$ctx2.sendIdx["at:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)})}));
+$6=_st($3)._putBlock_((function(x,y){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(_st(x)._root())._at_("foo"))._at_put_((2),y);
-}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1)})}));
-model=$2;
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)})}));
+model=$6;
 _st(isolator)._model_modify_(model,(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,3)})}));
 self._assert_equals_([(1), [(2), (5)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelGetsAppropriateValueForModification",{isolator:isolator,model:model,result:result},smalltalk.IsolatorTest)})},
 args: [],
 source: "testNontrivialModelGetsAppropriateValueForModification\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 5)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new\x0a\x09getBlock: [ :x | (x root at: 'foo') at: 2 ];\x0a\x09putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].\x0aisolator model: model modify: [:r|result := r].\x0aself assert: #(1 #(2 5)) equals: result",
-messageSends: ["on:", "->", "getBlock:", "at:", "root", "new", "putBlock:", "at:put:", "model:modify:", "assert:equals:"],
+messageSends: ["on:", "->", "getBlock:", "new", "at:", "root", "putBlock:", "at:put:", "model:modify:", "assert:equals:"],
 referencedClasses: ["Isolator", "EavModel"]
 }),
 smalltalk.IsolatorTest);
@@ -77,39 +85,54 @@ var isolator,model,result;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 function $EavModel(){return smalltalk.EavModel||(typeof EavModel=="undefined"?nil:EavModel)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $2,$3,$1,$4,$6,$5,$7,$9,$8;
 result=nil;
-isolator=_st($Isolator())._on_(smalltalk.HashedCollection._from_(["foo".__minus_gt(["bar", [(1), [(2), (3)]], "baz"]),"moo".__minus_gt("zoo")]));
-$1=_st($EavModel())._new();
-_st($1)._getBlock_((function(x){
+$2="foo".__minus_gt(["bar", [(1), [(2), (3)]], "baz"]);
+$ctx1.sendIdx["->"]=1;
+$3="moo".__minus_gt("zoo");
+$ctx1.sendIdx["->"]=2;
+$1=smalltalk.HashedCollection._from_([$2,$3]);
+isolator=_st($Isolator())._on_($1);
+$4=_st($EavModel())._new();
+_st($4)._getBlock_((function(x){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(_st(x)._root())._at_("foo"))._at_((2));
-}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})}));
-$2=_st($1)._putBlock_((function(x,y){
+$6=_st(x)._root();
+$ctx2.sendIdx["root"]=1;
+$5=_st($6)._at_("foo");
+$ctx2.sendIdx["at:"]=2;
+return _st($5)._at_((2));
+$ctx2.sendIdx["at:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)})}));
+$7=_st($4)._putBlock_((function(x,y){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(_st(x)._root())._at_("foo"))._at_put_((2),y);
-}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1)})}));
-model=$2;
+}, function($ctx2) {$ctx2.fillBlock({x:x,y:y},$ctx1,2)})}));
+model=$7;
 _st(isolator)._model_modify_(model,(function(r){
 return smalltalk.withContext(function($ctx2) {
 return "new";
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,3)})}));
 _st(isolator)._model_read_(model,(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,4)})}));
+$ctx1.sendIdx["model:read:"]=1;
 self._assert_equals_("new",result);
+$ctx1.sendIdx["assert:equals:"]=1;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
-self._assert_equals_(smalltalk.HashedCollection._from_(["foo".__minus_gt(["bar", "new", "baz"]),"moo".__minus_gt("zoo")]),result);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,5)})}));
+$9="foo".__minus_gt(["bar", "new", "baz"]);
+$ctx1.sendIdx["->"]=3;
+$8=smalltalk.HashedCollection._from_([$9,"moo".__minus_gt("zoo")]);
+self._assert_equals_($8,result);
 return self}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelModifiesAppropriateValue",{isolator:isolator,model:model,result:result},smalltalk.IsolatorTest)})},
 args: [],
 source: "testNontrivialModelModifiesAppropriateValue\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new\x0a\x09getBlock: [ :x | (x root at: 'foo') at: 2 ];\x0a\x09putBlock: [ :x :y | (x root at: 'foo') at: 2 put: y].\x0aisolator model: model modify: [:r|#new].\x0aisolator model: model read: [:r|result := r].\x0aself assert: #new equals: result.\x0aisolator model: rootModel read: [:r|result := r].\x0aself assert: #{ 'foo' -> #('bar' #new 'baz'). 'moo' -> 'zoo' } equals: result",
-messageSends: ["on:", "->", "getBlock:", "at:", "root", "new", "putBlock:", "at:put:", "model:modify:", "model:read:", "assert:equals:"],
+messageSends: ["on:", "->", "getBlock:", "new", "at:", "root", "putBlock:", "at:put:", "model:modify:", "model:read:", "assert:equals:"],
 referencedClasses: ["Isolator", "EavModel"]
 }),
 smalltalk.IsolatorTest);
@@ -124,22 +147,27 @@ var isolator,model,result;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 function $EavModel(){return smalltalk.EavModel||(typeof EavModel=="undefined"?nil:EavModel)}
 return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
 result=nil;
-isolator=_st($Isolator())._on_(smalltalk.HashedCollection._from_(["foo".__minus_gt(["bar", [(1), [(2), (3)]], "baz"]),"moo".__minus_gt("zoo")]));
+$2="foo".__minus_gt(["bar", [(1), [(2), (3)]], "baz"]);
+$ctx1.sendIdx["->"]=1;
+$1=smalltalk.HashedCollection._from_([$2,"moo".__minus_gt("zoo")]);
+isolator=_st($Isolator())._on_($1);
 model=_st(_st($EavModel())._new())._getBlock_((function(x){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(_st(x)._root())._at_("foo"))._at_((2));
-}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})}));
+$ctx2.sendIdx["at:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1,1)})}));
 _st(isolator)._model_read_(model,(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 self._assert_equals_([(1), [(2), (3)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testNontrivialModelReturnsAppropriateValue",{isolator:isolator,model:model,result:result},smalltalk.IsolatorTest)})},
 args: [],
 source: "testNontrivialModelReturnsAppropriateValue\x0a| isolator model result |\x0aresult := nil.\x0aisolator := Isolator on: #{ 'foo' -> #('bar' #(1 #(2 3)) 'baz'). 'moo' -> 'zoo' }.\x0amodel := EavModel new getBlock: [ :x | (x root at: 'foo') at: 2 ].\x0aisolator model: model read: [:r|result := r].\x0aself assert: #(1 #(2 3)) equals: result",
-messageSends: ["on:", "->", "getBlock:", "at:", "root", "new", "model:read:", "assert:equals:"],
+messageSends: ["on:", "->", "getBlock:", "new", "at:", "root", "model:read:", "assert:equals:"],
 referencedClasses: ["Isolator", "EavModel"]
 }),
 smalltalk.IsolatorTest);
@@ -158,12 +186,12 @@ isolator=_st($Isolator())._on_([(1), [(2), (3)]]);
 _st(isolator)._model_modify_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 return _st(r)._second();
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 self._assert_equals_([(2), (3)],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelExaminesThenModifiesRoot",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],
@@ -188,7 +216,7 @@ _st(isolator)._model_modify_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 self._assert_equals_([(2), [(1), (0)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelGetsRootForModification",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],
@@ -215,14 +243,16 @@ return smalltalk.withContext(function($ctx2) {
 newValue=r;
 newValue;
 _st(r)._at_put_((1),(4));
+$ctx2.sendIdx["at:put:"]=1;
 return r;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 _st(newValue)._at_put_((2),"bar");
+$ctx1.sendIdx["at:put:"]=2;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 _st(newValue)._at_put_((2),"baz");
 self._assert_equals_([(4), [(2), (3)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndDeeplyIsolatesInPlaceModifiedRoot",{isolator:isolator,result:result,newValue:newValue},smalltalk.IsolatorTest)})},
@@ -242,19 +272,25 @@ var self=this;
 var isolator,result,newValue;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
 result=nil;
 isolator=_st($Isolator())._on_([(1), [(2), (3)]]);
-newValue=smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]);
+$1="foo".__minus_gt([(4), (5), (6)]);
+$ctx1.sendIdx["->"]=1;
+newValue=smalltalk.HashedCollection._from_([$1]);
 _st(isolator)._model_modify_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 return newValue;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
-_st(_st(newValue)._at_("foo"))._at_put_((1),"bar");
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
+$2=_st(newValue)._at_("foo");
+$ctx1.sendIdx["at:"]=1;
+_st($2)._at_put_((1),"bar");
+$ctx1.sendIdx["at:put:"]=1;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 _st(_st(newValue)._at_("foo"))._at_put_((3),"baz");
 self._assert_equals_(smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]),result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndDeeplyIsolatesRoot",{isolator:isolator,result:result,newValue:newValue},smalltalk.IsolatorTest)})},
@@ -274,19 +310,23 @@ var self=this;
 var isolator,result,newValue;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 result=nil;
 isolator=_st($Isolator())._on_([(1), [(2), (3)]]);
-newValue=smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]);
+$1="foo".__minus_gt([(4), (5), (6)]);
+$ctx1.sendIdx["->"]=1;
+newValue=smalltalk.HashedCollection._from_([$1]);
 _st(isolator)._model_modify_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 return newValue;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 _st(newValue)._at_put_("foo","bar");
+$ctx1.sendIdx["at:put:"]=1;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 _st(newValue)._at_put_("foo","baz");
 self._assert_equals_(smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]),result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesAndIsolatesRoot",{isolator:isolator,result:result,newValue:newValue},smalltalk.IsolatorTest)})},
@@ -306,17 +346,20 @@ var self=this;
 var isolator,result;
 function $Isolator(){return smalltalk.Isolator||(typeof Isolator=="undefined"?nil:Isolator)}
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 result=nil;
 isolator=_st($Isolator())._on_([(1), [(2), (3)]]);
 _st(isolator)._model_modify_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
-return smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]);
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+$1="foo".__minus_gt([(4), (5), (6)]);
+$ctx2.sendIdx["->"]=1;
+return smalltalk.HashedCollection._from_([$1]);
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 self._assert_equals_(smalltalk.HashedCollection._from_(["foo".__minus_gt([(4), (5), (6)])]),result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelModifiesRoot",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],
@@ -340,12 +383,13 @@ isolator=_st($Isolator())._on_([(1), [(2), (3)]]);
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(r)._at_((2)))._at_put_((1),(0));
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
+$ctx1.sendIdx["model:read:"]=1;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 self._assert_equals_([(1), [(2), (3)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsDeeplyIsolatedRoot",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],
@@ -369,12 +413,13 @@ isolator=_st($Isolator())._on_([(1), [(2), (4)]]);
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 return _st(r)._at_put_((2),nil);
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
+$ctx1.sendIdx["model:read:"]=1;
 _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,2)})}));
 self._assert_equals_([(1), [(2), (4)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsIsolatedRoot",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],
@@ -399,7 +444,7 @@ _st(isolator)._model_read_(self["@rootModel"],(function(r){
 return smalltalk.withContext(function($ctx2) {
 result=r;
 return result;
-}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({r:r},$ctx1,1)})}));
 self._assert_equals_([(1), [(2), (3)]],result);
 return self}, function($ctx1) {$ctx1.fill(self,"testRootModelReturnsRoot",{isolator:isolator,result:result},smalltalk.IsolatorTest)})},
 args: [],