Ver código fonte

inspectOn: now sets list of associations

This is breaking for old-style inspectors
assuming a Dictionary in setVariables: send.

OTOH, (1 to: 25000) inspect now takes ~3 seconds, not a minute.
Herby Vojčík 4 anos atrás
pai
commit
fe8c0c74e9

+ 12 - 0
CHANGELOG

@@ -1,3 +1,15 @@
+14 Apr 2020 - Release 0.27.0
+===================================
+
+* Inspectors protocol is changed.
+  * The inspectOn: now sets list of associations in setVariables:.
+    * Breaking for objects acting as inspectors that assume Dictionary.
+    * Both IDEs were updated to assoc-list first, with backward compat.
+    * Inspecting big (~10k) collections is drastically faster.
+
+Commits: https://lolg.it/amber/amber/commits/0.27.0
+
+
 13 Apr 2020 - Release 0.26.0
 ===================================
 

+ 5 - 0
lang/API-CHANGES.txt

@@ -1,3 +1,8 @@
+0.27.0:
+
++ JSObjectProxy class >>
+  + associationsOfProxy:
+
 0.26.0:
 
 * Deprecate $core.seamless.

+ 30 - 0
lang/src/Kernel-Infrastructure.js

@@ -638,6 +638,36 @@ return self;
 }; }),
 $globals.JSObjectProxy.a$cls);
 
+$core.addMethod(
+$core.method({
+selector: "associationsOfProxy:",
+protocol: "proxy",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aProxy"],
+source: "associationsOfProxy: aProxy\x0a\x09<inlineJS: '\x0a\x09\x09var jsObject = aProxy.jsObject, result = [];\x0a\x09\x09for(var i in jsObject) {\x0a\x09\x09\x09result.push(i.__minus_gt(jsObject[i]));\x0a\x09\x09}\x0a\x09\x09return result;\x0a\x09'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [["inlineJS:", ["\x0a\x09\x09var jsObject = aProxy.jsObject, result = [];\x0a\x09\x09for(var i in jsObject) {\x0a\x09\x09\x09result.push(i.__minus_gt(jsObject[i]));\x0a\x09\x09}\x0a\x09\x09return result;\x0a\x09"]]],
+messageSends: []
+}, function ($methodClass){ return function (aProxy){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+
+		var jsObject = aProxy.jsObject, result = [];
+		for(var i in jsObject) {
+			result.push(i.__minus_gt(jsObject[i]));
+		}
+		return result;
+	;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"associationsOfProxy:",{aProxy:aProxy})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.JSObjectProxy.a$cls);
+
 $core.addMethod(
 $core.method({
 selector: "compareJSObjectOfProxy:withProxy:",

+ 10 - 0
lang/src/Kernel-Infrastructure.st

@@ -209,6 +209,16 @@ addObjectVariablesTo: aDictionary ofProxy: aProxy
 	'>
 !
 
+associationsOfProxy: aProxy
+	<inlineJS: '
+		var jsObject = aProxy.jsObject, result = [];
+		for(var i in jsObject) {
+			result.push(i.__minus_gt(jsObject[i]));
+		}
+		return result;
+	'>
+!
+
 compareJSObjectOfProxy: aProxy withProxy: anotherProxy
 <inlineJS: '
 	var anotherJSObject = anotherProxy.a$cls ? anotherProxy.jsObject : anotherProxy;

+ 191 - 89
lang/src/Platform-Services.js

@@ -1952,35 +1952,34 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#keys' put: self keys.\x0a\x09self keysAndValuesDo: [ :key :value |\x0a\x09\x09variables at: key put: value ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream\x0a\x09\x09\x09nextPut: '#self' -> self;\x0a\x09\x09\x09nextPut: '#keys' -> self keys;\x0a\x09\x09\x09nextPutAll: self associations ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "keys", "keysAndValuesDo:", "setLabel:", "shortenedPrintString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "keys", "nextPutAll:", "associations", "setLabel:", "shortenedPrintString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+return $core.withContext(function($ctx2) {
 //>>excludeEnd("ctx");
-][0];
-[$recv(variables)._at_put_("#keys",$self._keys())
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=2
+,$ctx2.sendIdx["->"]=1
 //>>excludeEnd("ctx");
-][0];
-$self._keysAndValuesDo_((function(key,value){
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
-return $recv(variables)._at_put_(key,value);
+][0];
+$recv(stream)._nextPut_("#keys".__minus_gt($self._keys()));
+return $recv(stream)._nextPutAll_($self._associations());
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1,1)});
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
 $recv(anInspector)._setLabel_($self._shortenedPrintString());
@@ -1998,40 +1997,52 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables i |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09i := 1.\x0a\x09self do: [ :each |\x0a\x09\x09variables at: i put: each.\x0a\x09\x09i := i + 1 ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09| i |\x0a\x09\x09stream nextPut: '#self' -> self.\x0a\x09\x09i := 1.\x0a\x09\x09self do: [ :each |\x0a\x09\x09\x09stream nextPut: i -> each.\x0a\x09\x09\x09i := i + 1 ] ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "do:", "+", "setLabel:", "shortenedPrintString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "do:", "+", "setLabel:", "shortenedPrintString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
-var variables,i;
+var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
+var i;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=1
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
 ][0];
 i=(1);
-$self._do_((function(each){
+return $self._do_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
+return $core.withContext(function($ctx3) {
 //>>excludeEnd("ctx");
-$recv(variables)._at_put_(i,each);
+$recv(stream)._nextPut_($recv(i).__minus_gt(each));
 i=$recv(i).__plus((1));
 return i;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream,i:i},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
 $recv(anInspector)._setLabel_($self._shortenedPrintString());
 $recv(anInspector)._setVariables_(variables);
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables,i:i})});
+}, function($ctx1) {$ctx1.fill(self,"inspectOn:",{anInspector:anInspector,variables:variables})});
 //>>excludeEnd("ctx");
 }; }),
 $globals.Collection);
@@ -2042,54 +2053,89 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#year' put: self year.\x0a\x09variables at: '#month' put: self month.\x0a\x09variables at: '#day' put: self day.\x0a\x09variables at: '#hours' put: self hours.\x0a\x09variables at: '#minutes' put: self minutes.\x0a\x09variables at: '#seconds' put: self seconds.\x0a\x09variables at: '#milliseconds' put: self milliseconds.\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream\x0a\x09\x09\x09nextPut: '#self' -> self;\x0a\x09\x09\x09nextPut: '#year' -> self year;\x0a\x09\x09\x09nextPut: '#month' -> self month;\x0a\x09\x09\x09nextPut: '#day' -> self day;\x0a\x09\x09\x09nextPut: '#hours' -> self hours;\x0a\x09\x09\x09nextPut: '#minutes' -> self minutes;\x0a\x09\x09\x09nextPut: '#seconds' -> self seconds;\x0a\x09\x09\x09nextPut: '#milliseconds' -> self milliseconds ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "year", "month", "day", "hours", "minutes", "seconds", "milliseconds", "setLabel:", "printString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "year", "month", "day", "hours", "minutes", "seconds", "milliseconds", "setLabel:", "printString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+,$ctx2.sendIdx["->"]=1
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#year",$self._year())
+[$recv(stream)._nextPut_(["#year".__minus_gt($self._year())
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=2
+,$ctx2.sendIdx["->"]=2
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=2
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#month",$self._month())
+[$recv(stream)._nextPut_(["#month".__minus_gt($self._month())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=3
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=3
+,$ctx2.sendIdx["nextPut:"]=3
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#day",$self._day())
+[$recv(stream)._nextPut_(["#day".__minus_gt($self._day())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=4
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=4
+,$ctx2.sendIdx["nextPut:"]=4
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#hours",$self._hours())
+[$recv(stream)._nextPut_(["#hours".__minus_gt($self._hours())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=5
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=5
+,$ctx2.sendIdx["nextPut:"]=5
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#minutes",$self._minutes())
+[$recv(stream)._nextPut_(["#minutes".__minus_gt($self._minutes())
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=6
+,$ctx2.sendIdx["->"]=6
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=6
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#seconds",$self._seconds())
+[$recv(stream)._nextPut_(["#seconds".__minus_gt($self._seconds())
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=7
+,$ctx2.sendIdx["->"]=7
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=7
 //>>excludeEnd("ctx");
 ][0];
-$recv(variables)._at_put_("#milliseconds",$self._milliseconds());
+return $recv(stream)._nextPut_("#milliseconds".__minus_gt($self._milliseconds()));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
 $recv(anInspector)._setLabel_($self._printString());
 $recv(anInspector)._setVariables_(variables);
 return self;
@@ -2105,21 +2151,28 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self jsObject.\x0a\x09anInspector setLabel: self printString.\x0a\x09JSObjectProxy addObjectVariablesTo: variables ofProxy: self.\x0a\x09anInspector setVariables: variables",
-referencedClasses: ["Dictionary", "JSObjectProxy"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream\x0a\x09\x09\x09nextPut: '#self' -> self jsObject;\x0a\x09\x09\x09nextPutAll: (JSObjectProxy associationsOfProxy: self) ].\x0a\x09anInspector setLabel: self printString.\x0a\x09anInspector setVariables: variables",
+referencedClasses: ["Array", "JSObjectProxy"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "jsObject", "setLabel:", "printString", "addObjectVariablesTo:ofProxy:", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "jsObject", "nextPutAll:", "associationsOfProxy:", "setLabel:", "printString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-$recv(variables)._at_put_("#self",$self._jsObject());
+variables=$recv($globals.Array)._streamContents_((function(stream){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+$recv(stream)._nextPut_("#self".__minus_gt($self._jsObject()));
+return $recv(stream)._nextPutAll_($recv($globals.JSObjectProxy)._associationsOfProxy_(self));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
 $recv(anInspector)._setLabel_($self._printString());
-$recv($globals.JSObjectProxy)._addObjectVariablesTo_ofProxy_(variables,self);
 $recv(anInspector)._setVariables_(variables);
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -2134,30 +2187,41 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09self class allInstanceVariableNames do: [ :each |\x0a\x09\x09variables at: each put: (self instVarNamed: each) ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream nextPut: '#self' -> self.\x0a\x09\x09self class allInstanceVariableNames do: [ :each |\x0a\x09\x09\x09stream nextPut: each -> (self instVarNamed: each) ] ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "do:", "allInstanceVariableNames", "class", "instVarNamed:", "setLabel:", "printString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "do:", "allInstanceVariableNames", "class", "instVarNamed:", "setLabel:", "printString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=1
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
 ][0];
-$recv($recv($self._class())._allInstanceVariableNames())._do_((function(each){
+return $recv($recv($self._class())._allInstanceVariableNames())._do_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
+return $core.withContext(function($ctx3) {
 //>>excludeEnd("ctx");
-return $recv(variables)._at_put_(each,$self._instVarNamed_(each));
+return $recv(stream)._nextPut_($recv(each).__minus_gt($self._instVarNamed_(each)));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
 $recv(anInspector)._setLabel_($self._printString());
@@ -2199,30 +2263,41 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09self withIndexDo: [ :each :i |\x0a\x09\x09variables at: i put: each ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream nextPut: '#self' -> self.\x0a\x09\x09self withIndexDo: [ :each :i |\x0a\x09\x09\x09stream nextPut: i -> each ] ].\x0a\x09anInspector\x0a\x09\x09setLabel: self shortenedPrintString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "withIndexDo:", "setLabel:", "shortenedPrintString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "withIndexDo:", "setLabel:", "shortenedPrintString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=1
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
 ][0];
-$self._withIndexDo_((function(each,i){
+return $self._withIndexDo_((function(each,i){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
+return $core.withContext(function($ctx3) {
+//>>excludeEnd("ctx");
+return $recv(stream)._nextPut_($recv(i).__minus_gt(each));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx3) {$ctx3.fillBlock({each:each,i:i},$ctx2,2)});
 //>>excludeEnd("ctx");
-return $recv(variables)._at_put_(i,each);
+}));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each,i:i},$ctx1,1)});
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
 $recv(anInspector)._setLabel_($self._shortenedPrintString());
@@ -2240,50 +2315,77 @@ selector: "inspectOn:",
 protocol: "*Platform-Services",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["anInspector"],
-source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Dictionary new.\x0a\x09variables at: '#self' put: self.\x0a\x09variables at: '#home' put: self home.\x0a\x09variables at: '#receiver' put: self receiver.\x0a\x09variables at: '#selector' put: self selector.\x0a\x09variables at: '#locals' put: self locals.\x0a\x09self class instanceVariableNames do: [ :each |\x0a\x09\x09variables at: each put: (self instVarNamed: each) ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
-referencedClasses: ["Dictionary"],
+source: "inspectOn: anInspector\x0a\x09| variables |\x0a\x09variables := Array streamContents: [ :stream |\x0a\x09\x09stream\x0a\x09\x09\x09nextPut: '#self' -> self;\x0a\x09\x09\x09nextPut: '#home' -> self home;\x0a\x09\x09\x09nextPut: '#receiver' -> self receiver;\x0a\x09\x09\x09nextPut: '#selector' -> self selector;\x0a\x09\x09\x09nextPut: '#locals' -> self locals.\x0a\x09self class instanceVariableNames do: [ :each |\x0a\x09\x09stream nextPut: each -> (self instVarNamed: each) ] ].\x0a\x09anInspector\x0a\x09\x09setLabel: self printString;\x0a\x09\x09setVariables: variables",
+referencedClasses: ["Array"],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["new", "at:put:", "home", "receiver", "selector", "locals", "do:", "instanceVariableNames", "class", "instVarNamed:", "setLabel:", "printString", "setVariables:"]
+messageSends: ["streamContents:", "nextPut:", "->", "home", "receiver", "selector", "locals", "do:", "instanceVariableNames", "class", "instVarNamed:", "setLabel:", "printString", "setVariables:"]
 }, function ($methodClass){ return function (anInspector){
 var self=this,$self=this;
 var variables;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-variables=$recv($globals.Dictionary)._new();
-[$recv(variables)._at_put_("#self",self)
+variables=$recv($globals.Array)._streamContents_((function(stream){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+[$recv(stream)._nextPut_(["#self".__minus_gt(self)
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=1
+,$ctx2.sendIdx["->"]=1
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=1
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#home",$self._home())
+[$recv(stream)._nextPut_(["#home".__minus_gt($self._home())
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=2
+,$ctx2.sendIdx["->"]=2
+//>>excludeEnd("ctx");
+][0])
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["nextPut:"]=2
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#receiver",$self._receiver())
+[$recv(stream)._nextPut_(["#receiver".__minus_gt($self._receiver())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=3
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=3
+,$ctx2.sendIdx["nextPut:"]=3
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#selector",$self._selector())
+[$recv(stream)._nextPut_(["#selector".__minus_gt($self._selector())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=4
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=4
+,$ctx2.sendIdx["nextPut:"]=4
 //>>excludeEnd("ctx");
 ][0];
-[$recv(variables)._at_put_("#locals",$self._locals())
+[$recv(stream)._nextPut_(["#locals".__minus_gt($self._locals())
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx2.sendIdx["->"]=5
+//>>excludeEnd("ctx");
+][0])
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-,$ctx1.sendIdx["at:put:"]=5
+,$ctx2.sendIdx["nextPut:"]=5
 //>>excludeEnd("ctx");
 ][0];
-$recv($recv($self._class())._instanceVariableNames())._do_((function(each){
+return $recv($recv($self._class())._instanceVariableNames())._do_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-return $core.withContext(function($ctx2) {
+return $core.withContext(function($ctx3) {
 //>>excludeEnd("ctx");
-return $recv(variables)._at_put_(each,$self._instVarNamed_(each));
+return $recv(stream)._nextPut_($recv(each).__minus_gt($self._instVarNamed_(each)));
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2,2)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)});
 //>>excludeEnd("ctx");
 }));
 $recv(anInspector)._setLabel_($self._printString());

+ 43 - 39
lang/src/Platform-Services.st

@@ -534,11 +534,11 @@ show: anObject
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	variables at: '#keys' put: self keys.
-	self keysAndValuesDo: [ :key :value |
-		variables at: key put: value ].
+	variables := Array streamContents: [ :stream |
+		stream
+			nextPut: '#self' -> self;
+			nextPut: '#keys' -> self keys;
+			nextPutAll: self associations ].
 	anInspector
 		setLabel: self shortenedPrintString;
 		setVariables: variables
@@ -547,13 +547,14 @@ inspectOn: anInspector
 !Collection methodsFor: '*Platform-Services'!
 
 inspectOn: anInspector
-	| variables i |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	i := 1.
-	self do: [ :each |
-		variables at: i put: each.
-		i := i + 1 ].
+	| variables |
+	variables := Array streamContents: [ :stream |
+		| i |
+		stream nextPut: '#self' -> self.
+		i := 1.
+		self do: [ :each |
+			stream nextPut: i -> each.
+			i := i + 1 ] ].
 	anInspector
 		setLabel: self shortenedPrintString;
 		setVariables: variables
@@ -563,15 +564,16 @@ inspectOn: anInspector
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	variables at: '#year' put: self year.
-	variables at: '#month' put: self month.
-	variables at: '#day' put: self day.
-	variables at: '#hours' put: self hours.
-	variables at: '#minutes' put: self minutes.
-	variables at: '#seconds' put: self seconds.
-	variables at: '#milliseconds' put: self milliseconds.
+	variables := Array streamContents: [ :stream |
+		stream
+			nextPut: '#self' -> self;
+			nextPut: '#year' -> self year;
+			nextPut: '#month' -> self month;
+			nextPut: '#day' -> self day;
+			nextPut: '#hours' -> self hours;
+			nextPut: '#minutes' -> self minutes;
+			nextPut: '#seconds' -> self seconds;
+			nextPut: '#milliseconds' -> self milliseconds ].
 	anInspector
 		setLabel: self printString;
 		setVariables: variables
@@ -581,10 +583,11 @@ inspectOn: anInspector
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self jsObject.
+	variables := Array streamContents: [ :stream |
+		stream
+			nextPut: '#self' -> self jsObject;
+			nextPutAll: (JSObjectProxy associationsOfProxy: self) ].
 	anInspector setLabel: self printString.
-	JSObjectProxy addObjectVariablesTo: variables ofProxy: self.
 	anInspector setVariables: variables
 ! !
 
@@ -592,10 +595,10 @@ inspectOn: anInspector
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	self class allInstanceVariableNames do: [ :each |
-		variables at: each put: (self instVarNamed: each) ].
+	variables := Array streamContents: [ :stream |
+		stream nextPut: '#self' -> self.
+		self class allInstanceVariableNames do: [ :each |
+			stream nextPut: each -> (self instVarNamed: each) ] ].
 	anInspector
 		setLabel: self printString;
 		setVariables: variables
@@ -612,10 +615,10 @@ do: aBlock displayingProgress: aString
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	self withIndexDo: [ :each :i |
-		variables at: i put: each ].
+	variables := Array streamContents: [ :stream |
+		stream nextPut: '#self' -> self.
+		self withIndexDo: [ :each :i |
+			stream nextPut: i -> each ] ].
 	anInspector
 		setLabel: self shortenedPrintString;
 		setVariables: variables
@@ -625,14 +628,15 @@ inspectOn: anInspector
 
 inspectOn: anInspector
 	| variables |
-	variables := Dictionary new.
-	variables at: '#self' put: self.
-	variables at: '#home' put: self home.
-	variables at: '#receiver' put: self receiver.
-	variables at: '#selector' put: self selector.
-	variables at: '#locals' put: self locals.
+	variables := Array streamContents: [ :stream |
+		stream
+			nextPut: '#self' -> self;
+			nextPut: '#home' -> self home;
+			nextPut: '#receiver' -> self receiver;
+			nextPut: '#selector' -> self selector;
+			nextPut: '#locals' -> self locals.
 	self class instanceVariableNames do: [ :each |
-		variables at: each put: (self instVarNamed: each) ].
+		stream nextPut: each -> (self instVarNamed: each) ] ].
 	anInspector
 		setLabel: self printString;
 		setVariables: variables