Browse Source

Merge pull request #790 from herby/lhf

Low hanging fruit
Nicolas Petton 11 years ago
parent
commit
76f6173945

+ 3 - 1
API-CHANGES.txt

@@ -9,7 +9,9 @@
 
 + CompiledMethod >>
   + defaultProtocol
-+ Behavior >> compile:protocol:
++ Behavior >>
+  + compile:protocol:
+  + removeProtocolIfEmpty:
 + Package >>
   + load
   + loadFromNamespace:

+ 3 - 3
js/Helios-Inspector.js

@@ -63,7 +63,7 @@ var selection;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
 selection=_st(self["@model"])._selection();
-$2=_st(_st(_st(self["@model"])._variables())._keys())._includes_(selection);
+$2=_st(_st(self["@model"])._variables())._includesKey_(selection);
 if(smalltalk.assert($2)){
 $1=_st(_st(self["@model"])._instVarObjectAt_(selection))._printString();
 } else {
@@ -72,8 +72,8 @@ $1="";
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selectionDisplayString",{selection:selection},smalltalk.HLInspectorDisplayWidget)})},
 args: [],
-source: "selectionDisplayString\x0a\x09|selection|\x0a\x09selection := model selection.\x0a    ^ (model variables keys includes: selection)\x0a    \x09ifTrue:[ (model instVarObjectAt: selection) printString ]\x0a      \x09ifFalse:[ '' ]",
-messageSends: ["selection", "ifTrue:ifFalse:", "includes:", "keys", "variables", "printString", "instVarObjectAt:"],
+source: "selectionDisplayString\x0a\x09|selection|\x0a\x09selection := model selection.\x0a    ^ (model variables includesKey: selection)\x0a    \x09ifTrue:[ (model instVarObjectAt: selection) printString ]\x0a      \x09ifFalse:[ '' ]",
+messageSends: ["selection", "ifTrue:ifFalse:", "includesKey:", "variables", "printString", "instVarObjectAt:"],
 referencedClasses: []
 }),
 smalltalk.HLInspectorDisplayWidget);

+ 17 - 26
js/IDE.js

@@ -2679,7 +2679,7 @@ fn: function (){
 var self=this;
 var klass;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4,$7,$8,$9,$6,$10,$5;
+var $1,$2,$3,$4,$7,$8,$6,$9,$5;
 $1=_st(self["@selectedTab"]).__eq("comment");
 $ctx1.sendIdx["="]=1;
 if(smalltalk.assert($1)){
@@ -2691,7 +2691,6 @@ if(($receiver = $3) == nil || $receiver == null){
 $3;
 } else {
 $4=_st(self["@selectedTab"]).__eq("instance");
-$ctx1.sendIdx["="]=2;
 if(smalltalk.assert($4)){
 klass=self["@selectedClass"];
 } else {
@@ -2705,28 +2704,22 @@ $8=klass;
 if(($receiver = $8) == nil || $receiver == null){
 $6=[];
 } else {
-$9=_st(klass)._methodDictionary();
-$ctx1.sendIdx["methodDictionary"]=1;
-$6=_st($9)._values();
-$ctx1.sendIdx["values"]=1;
+$6=_st(_st(klass)._methodDictionary())._values();
 };
 } else {
-$6=_st(_st(_st(klass)._methodDictionary())._values())._select_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(_st(each)._protocol()).__eq(self["@selectedProtocol"]);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,9)})}));
+$6=_st(klass)._methodsInProtocol_(self["@selectedProtocol"]);
 };
 $5=_st($6)._sort_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
-$10=_st(a)._selector();
+$9=_st(a)._selector();
 $ctx2.sendIdx["selector"]=1;
-return _st($10).__lt(_st(b)._selector());
-}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1,10)})}));
+return _st($9).__lt(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1,9)})}));
 return $5;
 }, function($ctx1) {$ctx1.fill(self,"methods",{klass:klass},smalltalk.Browser)})},
 args: [],
-source: "methods\x0a\x09| klass |\x0a\x09selectedTab = #comment ifTrue: [ ^ #() ].\x0a\x09selectedClass ifNotNil: [\x0a\x09klass := selectedTab = #instance\x0a\x09\x09ifTrue: [ selectedClass ]\x0a\x09\x09ifFalse: [ selectedClass class ]].\x0a\x09^ (selectedProtocol\x0a\x09ifNil: [\x0a\x09\x09klass\x0a\x09\x09ifNil: [ #() ]\x0a\x09\x09ifNotNil: [ klass methodDictionary values ]]\x0a\x09ifNotNil: [\x0a\x09\x09klass methodDictionary values select: [ :each |\x0a\x09\x09\x09each protocol = selectedProtocol ]]) \x0a\x09\x09\x09\x09sort: [ :a :b | a selector < b selector ]",
-messageSends: ["ifTrue:", "=", "ifNotNil:", "ifTrue:ifFalse:", "class", "sort:", "ifNil:ifNotNil:", "values", "methodDictionary", "select:", "protocol", "<", "selector"],
+source: "methods\x0a\x09| klass |\x0a\x09selectedTab = #comment ifTrue: [ ^ #() ].\x0a\x09selectedClass ifNotNil: [\x0a\x09klass := selectedTab = #instance\x0a\x09\x09ifTrue: [ selectedClass ]\x0a\x09\x09ifFalse: [ selectedClass class ]].\x0a\x09^ (selectedProtocol\x0a\x09ifNil: [\x0a\x09\x09klass\x0a\x09\x09ifNil: [ #() ]\x0a\x09\x09ifNotNil: [ klass methodDictionary values ]]\x0a\x09ifNotNil: [\x0a\x09\x09klass methodsInProtocol: selectedProtocol ]) \x0a\x09\x09\x09\x09sort: [ :a :b | a selector < b selector ]",
+messageSends: ["ifTrue:", "=", "ifNotNil:", "ifTrue:ifFalse:", "class", "sort:", "ifNil:ifNotNil:", "values", "methodDictionary", "methodsInProtocol:", "<", "selector"],
 referencedClasses: []
 }),
 smalltalk.Browser);
@@ -5343,7 +5336,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 _st(self["@variablesList"])._contents_((function(html){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(self._variables())._keys())._do_((function(each){
+return _st(self._variables())._keysDo_((function(each){
 var li;
 return smalltalk.withContext(function($ctx3) {
 li=_st(html)._li();
@@ -5363,8 +5356,8 @@ return _st(li)._class_("selected");
 }, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"updateVariablesList",{},smalltalk.Inspector)})},
 args: [],
-source: "updateVariablesList\x0a\x09variablesList contents: [ :html |\x0a\x09\x09self variables keys do: [ :each || li |\x0a\x09\x09\x09li := html li.\x0a\x09\x09\x09li\x0a\x09\x09\x09\x09with: each;\x0a\x09\x09\x09\x09onClick: [ self selectVariable: each ].\x0a\x09\x09\x09self selectedVariable = each ifTrue: [\x0a\x09\x09\x09\x09li class: 'selected' ]] ]",
-messageSends: ["contents:", "do:", "keys", "variables", "li", "with:", "onClick:", "selectVariable:", "ifTrue:", "=", "selectedVariable", "class:"],
+source: "updateVariablesList\x0a\x09variablesList contents: [ :html |\x0a\x09\x09self variables keysDo: [ :each || li |\x0a\x09\x09\x09li := html li.\x0a\x09\x09\x09li\x0a\x09\x09\x09\x09with: each;\x0a\x09\x09\x09\x09onClick: [ self selectVariable: each ].\x0a\x09\x09\x09self selectedVariable = each ifTrue: [\x0a\x09\x09\x09\x09li class: 'selected' ]] ]",
+messageSends: ["contents:", "keysDo:", "variables", "li", "with:", "onClick:", "selectVariable:", "ifTrue:", "=", "selectedVariable", "class:"],
 referencedClasses: []
 }),
 smalltalk.Inspector);
@@ -5871,7 +5864,7 @@ var $1;
 regex=_st(self["@selector"])._allButFirst();
 _st(self._classesAndMetaclasses())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(_st(each)._methodDictionary())._values())._do_((function(value){
+return _st(_st(each)._methodDictionary())._valuesDo_((function(value){
 return smalltalk.withContext(function($ctx3) {
 $1=_st(_st(value)._source())._match_(regex);
 if(smalltalk.assert($1)){
@@ -5879,11 +5872,10 @@ return _st(self._matches())._add_(value);
 };
 }, function($ctx3) {$ctx3.fillBlock({value:value},$ctx2,2)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
 return self}, function($ctx1) {$ctx1.fill(self,"searchMethodSource",{regex:regex},smalltalk.ReferencesBrowser)})},
 args: [],
-source: "searchMethodSource\x0a\x09| regex |\x0a\x09regex := selector allButFirst.\x0a\x09self classesAndMetaclasses do: [ :each |\x0a\x09\x09each methodDictionary values do: [ :value |\x0a\x09\x09\x09(value source match: regex) ifTrue: [\x0a\x09\x09\x09\x09self matches add: value ]] ]",
-messageSends: ["allButFirst", "do:", "classesAndMetaclasses", "values", "methodDictionary", "ifTrue:", "match:", "source", "add:", "matches"],
+source: "searchMethodSource\x0a\x09| regex |\x0a\x09regex := selector allButFirst.\x0a\x09self classesAndMetaclasses do: [ :each |\x0a\x09\x09each methodDictionary valuesDo: [ :value |\x0a\x09\x09\x09(value source match: regex) ifTrue: [\x0a\x09\x09\x09\x09self matches add: value ]] ]",
+messageSends: ["allButFirst", "do:", "classesAndMetaclasses", "valuesDo:", "methodDictionary", "ifTrue:", "match:", "source", "add:", "matches"],
 referencedClasses: []
 }),
 smalltalk.ReferencesBrowser);
@@ -5898,7 +5890,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 _st(self._classesAndMetaclasses())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(_st(each)._methodDictionary())._values())._do_((function(value){
+return _st(_st(each)._methodDictionary())._valuesDo_((function(value){
 return smalltalk.withContext(function($ctx3) {
 $2=_st(value)._referencedClasses();
 $ctx3.sendIdx["referencedClasses"]=1;
@@ -5908,11 +5900,10 @@ return _st(self._referencedClasses())._add_(value);
 };
 }, function($ctx3) {$ctx3.fillBlock({value:value},$ctx2,2)})}));
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
 return self}, function($ctx1) {$ctx1.fill(self,"searchReferencedClasses",{},smalltalk.ReferencesBrowser)})},
 args: [],
-source: "searchReferencedClasses\x0a\x09self classesAndMetaclasses do: [ :each |\x0a\x09\x09each methodDictionary values do: [ :value |\x0a\x09\x09\x09(value referencedClasses includes: selector) ifTrue: [\x0a\x09\x09\x09\x09self referencedClasses add: value ]] ]",
-messageSends: ["do:", "classesAndMetaclasses", "values", "methodDictionary", "ifTrue:", "includes:", "referencedClasses", "add:"],
+source: "searchReferencedClasses\x0a\x09self classesAndMetaclasses do: [ :each |\x0a\x09\x09each methodDictionary valuesDo: [ :value |\x0a\x09\x09\x09(value referencedClasses includes: selector) ifTrue: [\x0a\x09\x09\x09\x09self referencedClasses add: value ]] ]",
+messageSends: ["do:", "classesAndMetaclasses", "valuesDo:", "methodDictionary", "ifTrue:", "includes:", "referencedClasses", "add:"],
 referencedClasses: []
 }),
 smalltalk.ReferencesBrowser);

+ 69 - 72
js/Kernel-Classes.js

@@ -33,7 +33,7 @@ function $MethodAdded(){return smalltalk.MethodAdded||(typeof MethodAdded=="unde
 function $MethodModified(){return smalltalk.MethodModified||(typeof MethodModified=="undefined"?nil:MethodModified)}
 function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnnouncer=="undefined"?nil:SystemAnnouncer)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$1,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13;
+var $2,$3,$1,$4,$5,$6,$7,$8,$9,$10,$11;
 oldMethod=_st(self._methodDictionary())._at_ifAbsent_(_st(aMethod)._selector(),(function(){
 return smalltalk.withContext(function($ctx2) {
 return nil;
@@ -44,7 +44,6 @@ $ctx1.sendIdx["protocol"]=1;
 $1=_st($2)._includes_($3);
 if(! smalltalk.assert($1)){
 $4=self._organization();
-$ctx1.sendIdx["organization"]=1;
 $5=_st(aMethod)._protocol();
 $ctx1.sendIdx["protocol"]=2;
 _st($4)._addElement_($5);
@@ -54,39 +53,29 @@ $6=oldMethod;
 if(($receiver = $6) == nil || $receiver == null){
 $6;
 } else {
-_st(_st(self._methods())._select_((function(each){
-return smalltalk.withContext(function($ctx2) {
-$7=_st(each)._protocol();
-$ctx2.sendIdx["protocol"]=3;
-$8=_st(oldMethod)._protocol();
-$ctx2.sendIdx["protocol"]=4;
-return _st($7).__eq($8);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,4)})})))._ifEmpty_((function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(self._organization())._removeElement_(_st(oldMethod)._protocol());
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,5)})}));
+self._removeProtocolIfEmpty_(_st(oldMethod)._protocol());
 };
-$9=oldMethod;
-if(($receiver = $9) == nil || $receiver == null){
-$10=_st($MethodAdded())._new();
+$7=oldMethod;
+if(($receiver = $7) == nil || $receiver == null){
+$8=_st($MethodAdded())._new();
 $ctx1.sendIdx["new"]=1;
-_st($10)._method_(aMethod);
+_st($8)._method_(aMethod);
 $ctx1.sendIdx["method:"]=1;
-$11=_st($10)._yourself();
+$9=_st($8)._yourself();
 $ctx1.sendIdx["yourself"]=1;
-announcement=$11;
+announcement=$9;
 } else {
-$12=_st($MethodModified())._new();
-_st($12)._oldMethod_(oldMethod);
-_st($12)._method_(aMethod);
-$13=_st($12)._yourself();
-announcement=$13;
+$10=_st($MethodModified())._new();
+_st($10)._oldMethod_(oldMethod);
+_st($10)._method_(aMethod);
+$11=_st($10)._yourself();
+announcement=$11;
 };
 _st(_st($SystemAnnouncer())._current())._announce_(announcement);
 return self}, function($ctx1) {$ctx1.fill(self,"addCompiledMethod:",{aMethod:aMethod,oldMethod:oldMethod,announcement:announcement},smalltalk.Behavior)})},
 args: ["aMethod"],
-source: "addCompiledMethod: aMethod\x0a\x09| oldMethod announcement |\x0a\x09\x0a\x09oldMethod := self methodDictionary\x0a\x09\x09at: aMethod selector\x0a\x09\x09ifAbsent: [ nil ].\x0a\x09\x0a\x09(self protocols includes: aMethod protocol)\x0a\x09\x09ifFalse: [ self organization addElement: aMethod protocol ].\x0a\x0a\x09self basicAddCompiledMethod: aMethod.\x0a\x09\x0a\x09oldMethod ifNotNil: [\x0a\x09\x09(self methods\x0a\x09\x09\x09select: [ :each | each protocol = oldMethod protocol ])\x0a\x09\x09\x09ifEmpty: [ self organization removeElement: oldMethod protocol ] ].\x0a\x09\x0a\x09announcement := oldMethod\x0a\x09\x09ifNil: [\x0a\x09\x09\x09MethodAdded new\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ]\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09MethodModified new\x0a\x09\x09\x09\x09\x09oldMethod: oldMethod;\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ].\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09\x09\x09announce: announcement",
-messageSends: ["at:ifAbsent:", "methodDictionary", "selector", "ifFalse:", "includes:", "protocols", "protocol", "addElement:", "organization", "basicAddCompiledMethod:", "ifNotNil:", "ifEmpty:", "select:", "methods", "=", "removeElement:", "ifNil:ifNotNil:", "method:", "new", "yourself", "oldMethod:", "announce:", "current"],
+source: "addCompiledMethod: aMethod\x0a\x09| oldMethod announcement |\x0a\x09\x0a\x09oldMethod := self methodDictionary\x0a\x09\x09at: aMethod selector\x0a\x09\x09ifAbsent: [ nil ].\x0a\x09\x0a\x09(self protocols includes: aMethod protocol)\x0a\x09\x09ifFalse: [ self organization addElement: aMethod protocol ].\x0a\x0a\x09self basicAddCompiledMethod: aMethod.\x0a\x09\x0a\x09oldMethod ifNotNil: [\x0a\x09\x09self removeProtocolIfEmpty: oldMethod protocol ].\x0a\x09\x0a\x09announcement := oldMethod\x0a\x09\x09ifNil: [\x0a\x09\x09\x09MethodAdded new\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ]\x0a\x09\x09ifNotNil: [\x0a\x09\x09\x09MethodModified new\x0a\x09\x09\x09\x09\x09oldMethod: oldMethod;\x0a\x09\x09\x09\x09\x09method: aMethod;\x0a\x09\x09\x09\x09\x09yourself ].\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09\x09\x09announce: announcement",
+messageSends: ["at:ifAbsent:", "methodDictionary", "selector", "ifFalse:", "includes:", "protocols", "protocol", "addElement:", "organization", "basicAddCompiledMethod:", "ifNotNil:", "removeProtocolIfEmpty:", "ifNil:ifNotNil:", "method:", "new", "yourself", "oldMethod:", "announce:", "current"],
 referencedClasses: ["MethodAdded", "MethodModified", "SystemAnnouncer"]
 }),
 smalltalk.Behavior);
@@ -282,7 +271,7 @@ fn: function (aSelector){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $3,$2,$1;
-$1=_st(_st(_st(self._methodDictionary())._keys())._includes_(_st(aSelector)._asString()))._or_((function(){
+$1=_st(self._includesSelector_(_st(aSelector)._asString()))._or_((function(){
 return smalltalk.withContext(function($ctx2) {
 $3=self._superclass();
 $ctx2.sendIdx["superclass"]=1;
@@ -295,8 +284,8 @@ return _st(self._superclass())._canUnderstand_(aSelector);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"canUnderstand:",{aSelector:aSelector},smalltalk.Behavior)})},
 args: ["aSelector"],
-source: "canUnderstand: aSelector\x0a\x09^ (self methodDictionary keys includes: aSelector asString) or: [\x0a\x09\x09self superclass notNil and: [ self superclass canUnderstand: aSelector ]]",
-messageSends: ["or:", "includes:", "keys", "methodDictionary", "asString", "and:", "notNil", "superclass", "canUnderstand:"],
+source: "canUnderstand: aSelector\x0a\x09^ (self includesSelector: aSelector asString) or: [\x0a\x09\x09self superclass notNil and: [ self superclass canUnderstand: aSelector ]]",
+messageSends: ["or:", "includesSelector:", "asString", "and:", "notNil", "superclass", "canUnderstand:"],
 referencedClasses: []
 }),
 smalltalk.Behavior);
@@ -717,15 +706,15 @@ fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(_st(self._methodDictionary())._values())._select_((function(each){
+$1=_st(self._methods())._select_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(each)._protocol()).__eq(aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"methodsInProtocol:",{aString:aString},smalltalk.Behavior)})},
 args: ["aString"],
-source: "methodsInProtocol: aString\x0a\x09^ self methodDictionary values select: [ :each | each protocol = aString ]",
-messageSends: ["select:", "values", "methodDictionary", "=", "protocol"],
+source: "methodsInProtocol: aString\x0a\x09^ self methods select: [ :each | each protocol = aString ]",
+messageSends: ["select:", "methods", "=", "protocol"],
 referencedClasses: []
 }),
 smalltalk.Behavior);
@@ -860,22 +849,21 @@ function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
 methodsByProtocol=_st($HashedCollection())._new();
 $ctx1.sendIdx["new"]=1;
-_st(_st(self._methodDictionary())._values())._do_((function(m){
+_st(self._methodDictionary())._valuesDo_((function(m){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(methodsByProtocol)._at_ifAbsentPut_(_st(m)._protocol(),(function(){
 return smalltalk.withContext(function($ctx3) {
 return _st($Array())._new();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})})))._add_(m);
 }, function($ctx2) {$ctx2.fillBlock({m:m},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
 _st(self._protocols())._do_((function(protocol){
 return smalltalk.withContext(function($ctx2) {
 return _st(aBlock)._value_value_(protocol,_st(methodsByProtocol)._at_(protocol));
 }, function($ctx2) {$ctx2.fillBlock({protocol:protocol},$ctx1,3)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"protocolsDo:",{aBlock:aBlock,methodsByProtocol:methodsByProtocol},smalltalk.Behavior)})},
 args: ["aBlock"],
-source: "protocolsDo: aBlock\x0a\x09\x22Execute aBlock for each method protocol with\x0a\x09its collection of methods in the sort order of protocol name.\x22\x0a\x0a\x09| methodsByProtocol |\x0a\x09methodsByProtocol := HashedCollection new.\x0a\x09self methodDictionary values do: [ :m |\x0a\x09\x09(methodsByProtocol at: m protocol ifAbsentPut: [ Array new ])\x0a\x09\x09\x09add: m ].\x0a\x09self protocols do: [ :protocol |\x0a\x09\x09aBlock value: protocol value: (methodsByProtocol at: protocol) ]",
-messageSends: ["new", "do:", "values", "methodDictionary", "add:", "at:ifAbsentPut:", "protocol", "protocols", "value:value:", "at:"],
+source: "protocolsDo: aBlock\x0a\x09\x22Execute aBlock for each method protocol with\x0a\x09its collection of methods in the sort order of protocol name.\x22\x0a\x0a\x09| methodsByProtocol |\x0a\x09methodsByProtocol := HashedCollection new.\x0a\x09self methodDictionary valuesDo: [ :m |\x0a\x09\x09(methodsByProtocol at: m protocol ifAbsentPut: [ Array new ])\x0a\x09\x09\x09add: m ].\x0a\x09self protocols do: [ :protocol |\x0a\x09\x09aBlock value: protocol value: (methodsByProtocol at: protocol) ]",
+messageSends: ["new", "valuesDo:", "methodDictionary", "add:", "at:ifAbsentPut:", "protocol", "do:", "protocols", "value:value:", "at:"],
 referencedClasses: ["HashedCollection", "Array"]
 }),
 smalltalk.Behavior);
@@ -924,28 +912,40 @@ var self=this;
 function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnnouncer=="undefined"?nil:SystemAnnouncer)}
 function $MethodRemoved(){return smalltalk.MethodRemoved||(typeof MethodRemoved=="undefined"?nil:MethodRemoved)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
+var $1,$2;
 self._basicRemoveCompiledMethod_(aMethod);
+self._removeProtocolIfEmpty_(_st(aMethod)._protocol());
+$1=_st($MethodRemoved())._new();
+_st($1)._method_(aMethod);
+$2=_st($1)._yourself();
+_st(_st($SystemAnnouncer())._current())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"removeCompiledMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
+args: ["aMethod"],
+source: "removeCompiledMethod: aMethod\x0a\x09self basicRemoveCompiledMethod: aMethod.\x0a\x09\x0a\x09self removeProtocolIfEmpty: aMethod protocol.\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (MethodRemoved new\x0a\x09\x09\x09method: aMethod;\x0a\x09\x09\x09yourself)",
+messageSends: ["basicRemoveCompiledMethod:", "removeProtocolIfEmpty:", "protocol", "announce:", "current", "method:", "new", "yourself"],
+referencedClasses: ["SystemAnnouncer", "MethodRemoved"]
+}),
+smalltalk.Behavior);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "removeProtocolIfEmpty:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 _st(self._methods())._detect_ifNone_((function(each){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(each)._protocol();
-$ctx2.sendIdx["protocol"]=1;
-$2=_st(aMethod)._protocol();
-$ctx2.sendIdx["protocol"]=2;
-return _st($1).__eq($2);
+return _st(_st(each)._protocol()).__eq(aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(self._organization())._removeElement_(_st(aMethod)._protocol());
+return _st(self._organization())._removeElement_(aString);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
-$3=_st($MethodRemoved())._new();
-_st($3)._method_(aMethod);
-$4=_st($3)._yourself();
-_st(_st($SystemAnnouncer())._current())._announce_($4);
-return self}, function($ctx1) {$ctx1.fill(self,"removeCompiledMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
-args: ["aMethod"],
-source: "removeCompiledMethod: aMethod\x0a\x09self basicRemoveCompiledMethod: aMethod.\x0a\x09\x0a\x09self methods\x0a\x09\x09detect: [ :each | each protocol = aMethod protocol ]\x0a\x09\x09ifNone: [ self organization removeElement: aMethod protocol ].\x0a\x09\x0a\x09SystemAnnouncer current\x0a\x09\x09announce: (MethodRemoved new\x0a\x09\x09\x09method: aMethod;\x0a\x09\x09\x09yourself)",
-messageSends: ["basicRemoveCompiledMethod:", "detect:ifNone:", "methods", "=", "protocol", "removeElement:", "organization", "announce:", "current", "method:", "new", "yourself"],
-referencedClasses: ["SystemAnnouncer", "MethodRemoved"]
+return self}, function($ctx1) {$ctx1.fill(self,"removeProtocolIfEmpty:",{aString:aString},smalltalk.Behavior)})},
+args: ["aString"],
+source: "removeProtocolIfEmpty: aString\x0a\x09self methods\x0a\x09\x09detect: [ :each | each protocol = aString ]\x0a\x09\x09ifNone: [ self organization removeElement: aString ]",
+messageSends: ["detect:ifNone:", "methods", "=", "protocol", "removeElement:", "organization"],
+referencedClasses: []
 }),
 smalltalk.Behavior);
 
@@ -1744,43 +1744,40 @@ fn: function (aClass,anotherClass){
 var self=this;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1,$3,$4,$5,$6,$8,$7,$11,$10,$9;
+var $1,$2,$3,$4,$5,$7,$6,$9,$8;
 _st(anotherClass)._comment_(_st(aClass)._comment());
-$2=_st(aClass)._methodDictionary();
+$1=_st(aClass)._methodDictionary();
 $ctx1.sendIdx["methodDictionary"]=1;
-$1=_st($2)._values();
-$ctx1.sendIdx["values"]=1;
-_st($1)._do_((function(each){
+_st($1)._valuesDo_((function(each){
 return smalltalk.withContext(function($ctx2) {
-$3=_st($Compiler())._new();
+$2=_st($Compiler())._new();
 $ctx2.sendIdx["new"]=1;
-$4=_st(each)._source();
+$3=_st(each)._source();
 $ctx2.sendIdx["source"]=1;
-$5=_st(each)._protocol();
+$4=_st(each)._protocol();
 $ctx2.sendIdx["protocol"]=1;
-return _st($3)._install_forClass_protocol_($4,anotherClass,$5);
+return _st($2)._install_forClass_protocol_($3,anotherClass,$4);
 $ctx2.sendIdx["install:forClass:protocol:"]=1;
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
-$6=_st(anotherClass)._class();
+$ctx1.sendIdx["valuesDo:"]=1;
+$5=_st(anotherClass)._class();
 $ctx1.sendIdx["class"]=1;
-$8=_st(aClass)._class();
+$7=_st(aClass)._class();
 $ctx1.sendIdx["class"]=2;
-$7=_st($8)._instanceVariableNames();
-self._basicClass_instanceVariables_($6,$7);
-$11=_st(aClass)._class();
+$6=_st($7)._instanceVariableNames();
+self._basicClass_instanceVariables_($5,$6);
+$9=_st(aClass)._class();
 $ctx1.sendIdx["class"]=3;
-$10=_st($11)._methodDictionary();
-$9=_st($10)._values();
-_st($9)._do_((function(each){
+$8=_st($9)._methodDictionary();
+_st($8)._valuesDo_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st($Compiler())._new())._install_forClass_protocol_(_st(each)._source(),_st(anotherClass)._class(),_st(each)._protocol());
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
 self._setupClass_(anotherClass);
 return self}, function($ctx1) {$ctx1.fill(self,"copyClass:to:",{aClass:aClass,anotherClass:anotherClass},smalltalk.ClassBuilder)})},
 args: ["aClass", "anotherClass"],
-source: "copyClass: aClass to: anotherClass\x0a\x0a\x09anotherClass comment: aClass comment.\x0a\x0a\x09aClass methodDictionary values do: [ :each |\x0a\x09\x09Compiler new install: each source forClass: anotherClass protocol: each protocol ].\x0a\x0a\x09self basicClass: anotherClass class instanceVariables: aClass class instanceVariableNames.\x0a\x0a\x09aClass class methodDictionary values do: [ :each |\x0a\x09\x09Compiler new install: each source forClass: anotherClass class protocol: each protocol ].\x0a\x0a\x09self setupClass: anotherClass",
-messageSends: ["comment:", "comment", "do:", "values", "methodDictionary", "install:forClass:protocol:", "new", "source", "protocol", "basicClass:instanceVariables:", "class", "instanceVariableNames", "setupClass:"],
+source: "copyClass: aClass to: anotherClass\x0a\x0a\x09anotherClass comment: aClass comment.\x0a\x0a\x09aClass methodDictionary valuesDo: [ :each |\x0a\x09\x09Compiler new install: each source forClass: anotherClass protocol: each protocol ].\x0a\x0a\x09self basicClass: anotherClass class instanceVariables: aClass class instanceVariableNames.\x0a\x0a\x09aClass class methodDictionary valuesDo: [ :each |\x0a\x09\x09Compiler new install: each source forClass: anotherClass class protocol: each protocol ].\x0a\x0a\x09self setupClass: anotherClass",
+messageSends: ["comment:", "comment", "valuesDo:", "methodDictionary", "install:forClass:protocol:", "new", "source", "protocol", "basicClass:instanceVariables:", "class", "instanceVariableNames", "setupClass:"],
 referencedClasses: ["Compiler"]
 }),
 smalltalk.ClassBuilder);

+ 17 - 12
js/Kernel-Collections.js

@@ -3528,20 +3528,25 @@ selector: "remove:ifAbsent:",
 protocol: 'adding/removing',
 fn: function (anObject,aBlock){
 var self=this;
+var index;
 return smalltalk.withContext(function($ctx1) { 
-
-		for(var i=0;i<self.length;i++) {
-			if(_st(self[i]).__eq(anObject)) {
-				self.splice(i,1);
-				return self;
-			}
-		};
-		aBlock._value();
-	;
-return self}, function($ctx1) {$ctx1.fill(self,"remove:ifAbsent:",{anObject:anObject,aBlock:aBlock},smalltalk.Array)})},
+var $2,$1;
+index=self._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
+return (0);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$2=_st(index).__eq((0));
+if(smalltalk.assert($2)){
+$1=_st(aBlock)._value();
+} else {
+self._removeIndex_(index);
+$1=anObject;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"remove:ifAbsent:",{anObject:anObject,aBlock:aBlock,index:index},smalltalk.Array)})},
 args: ["anObject", "aBlock"],
-source: "remove: anObject ifAbsent: aBlock\x0a\x09<\x0a\x09\x09for(var i=0;i<self.length;i++) {\x0a\x09\x09\x09if(_st(self[i]).__eq(anObject)) {\x0a\x09\x09\x09\x09self.splice(i,1);\x0a\x09\x09\x09\x09return self;\x0a\x09\x09\x09}\x0a\x09\x09};\x0a\x09\x09aBlock._value();\x0a\x09>",
-messageSends: [],
+source: "remove: anObject ifAbsent: aBlock\x0a\x09| index |\x0a\x09index := self indexOf: anObject ifAbsent: [ 0 ].\x0a\x09^ index = 0\x0a\x09\x09ifFalse: [ self removeIndex: index. anObject ]\x0a\x09\x09ifTrue: [ aBlock value ]",
+messageSends: ["indexOf:ifAbsent:", "ifFalse:ifTrue:", "=", "removeIndex:", "value"],
 referencedClasses: []
 }),
 smalltalk.Array);

+ 8 - 14
js/Kernel-Infrastructure.js

@@ -710,17 +710,14 @@ protocol: 'actions',
 fn: function (aString,aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st(aClass)._methods())._select_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(_st(each)._protocol()).__eq(aString);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})})))._do_((function(each){
+_st(_st(aClass)._methodsInProtocol_(aString))._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(aClass)._removeCompiledMethod_(each);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeProtocol:from:",{aString:aString,aClass:aClass},smalltalk.Environment)})},
 args: ["aString", "aClass"],
-source: "removeProtocol: aString from: aClass\x0a\x09(aClass methods\x0a\x09\x09select: [ :each | each protocol = aString ])\x0a\x09\x09do: [ :each | aClass removeCompiledMethod: each ]",
-messageSends: ["do:", "select:", "methods", "=", "protocol", "removeCompiledMethod:"],
+source: "removeProtocol: aString from: aClass\x0a\x09(aClass methodsInProtocol: aString)\x0a\x09\x09do: [ :each | aClass removeCompiledMethod: each ]",
+messageSends: ["do:", "methodsInProtocol:", "removeCompiledMethod:"],
 referencedClasses: []
 }),
 smalltalk.Environment);
@@ -759,17 +756,14 @@ protocol: 'actions',
 fn: function (aString,anotherString,aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st(aClass)._methods())._select_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(_st(each)._protocol()).__eq(aString);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})})))._do_((function(each){
+_st(_st(aClass)._methodsInProtocol_(aString))._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._protocol_(anotherString);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"renameProtocol:to:in:",{aString:aString,anotherString:anotherString,aClass:aClass},smalltalk.Environment)})},
 args: ["aString", "anotherString", "aClass"],
-source: "renameProtocol: aString to: anotherString in: aClass\x0a\x09(aClass methods\x0a\x09\x09select: [ :each | each protocol = aString ])\x0a\x09\x09do: [ :each | each protocol: anotherString ]",
-messageSends: ["do:", "select:", "methods", "=", "protocol", "protocol:"],
+source: "renameProtocol: aString to: anotherString in: aClass\x0a\x09(aClass methodsInProtocol: aString)\x0a\x09\x09do: [ :each | each protocol: anotherString ]",
+messageSends: ["do:", "methodsInProtocol:", "protocol:"],
 referencedClasses: []
 }),
 smalltalk.Environment);

+ 7 - 21
js/Kernel-Methods.js

@@ -698,9 +698,8 @@ var oldProtocol;
 function $SystemAnnouncer(){return smalltalk.SystemAnnouncer||(typeof SystemAnnouncer=="undefined"?nil:SystemAnnouncer)}
 function $MethodMoved(){return smalltalk.MethodMoved||(typeof MethodMoved=="undefined"?nil:MethodMoved)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$5,$4,$8,$7,$6;
+var $1,$2,$3;
 oldProtocol=self._protocol();
-$ctx1.sendIdx["protocol"]=1;
 self._basicAt_put_("protocol",aString);
 $1=_st($MethodMoved())._new();
 _st($1)._method_(self);
@@ -708,31 +707,18 @@ _st($1)._oldProtocol_(oldProtocol);
 $2=_st($1)._yourself();
 _st(_st($SystemAnnouncer())._current())._announce_($2);
 $3=self._methodClass();
-$ctx1.sendIdx["methodClass"]=1;
 if(($receiver = $3) == nil || $receiver == null){
 $3;
 } else {
-$5=self._methodClass();
-$ctx1.sendIdx["methodClass"]=2;
-$4=_st($5)._organization();
-$ctx1.sendIdx["organization"]=1;
-_st($4)._addElement_(aString);
-$8=self._methodClass();
-$ctx1.sendIdx["methodClass"]=3;
-$7=_st($8)._methods();
-$6=_st($7)._select_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st(_st(each)._protocol()).__eq(oldProtocol);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
-_st($6)._ifEmpty_((function(){
-return smalltalk.withContext(function($ctx2) {
-return _st(_st(self._methodClass())._organization())._removeElement_(oldProtocol);
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)})}));
+var methodClass;
+methodClass=$receiver;
+_st(_st(methodClass)._organization())._addElement_(aString);
+_st(methodClass)._removeProtocolIfEmpty_(oldProtocol);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"protocol:",{aString:aString,oldProtocol:oldProtocol},smalltalk.CompiledMethod)})},
 args: ["aString"],
-source: "protocol: aString\x0a\x09| oldProtocol |\x0a\x09oldProtocol := self protocol.\x0a\x09self basicAt: 'protocol' put: aString.\x0a\x0a\x09SystemAnnouncer current announce: (MethodMoved new\x0a\x09\x09method: self;\x0a\x09\x09oldProtocol: oldProtocol;\x0a\x09\x09yourself).\x0a\x0a\x09self methodClass ifNotNil: [\x0a\x09\x09self methodClass organization addElement: aString.\x0a\x09\x0a\x09\x09(self methodClass methods\x0a\x09\x09\x09select: [ :each | each protocol = oldProtocol ])\x0a\x09\x09\x09ifEmpty: [ self methodClass organization removeElement: oldProtocol ] ]",
-messageSends: ["protocol", "basicAt:put:", "announce:", "current", "method:", "new", "oldProtocol:", "yourself", "ifNotNil:", "methodClass", "addElement:", "organization", "ifEmpty:", "select:", "methods", "=", "removeElement:"],
+source: "protocol: aString\x0a\x09| oldProtocol |\x0a\x09oldProtocol := self protocol.\x0a\x09self basicAt: 'protocol' put: aString.\x0a\x0a\x09SystemAnnouncer current announce: (MethodMoved new\x0a\x09\x09method: self;\x0a\x09\x09oldProtocol: oldProtocol;\x0a\x09\x09yourself).\x0a\x0a\x09self methodClass ifNotNil: [ :methodClass |\x0a\x09\x09methodClass organization addElement: aString.\x0a\x09\x09methodClass removeProtocolIfEmpty: oldProtocol ]",
+messageSends: ["protocol", "basicAt:put:", "announce:", "current", "method:", "new", "oldProtocol:", "yourself", "ifNotNil:", "methodClass", "addElement:", "organization", "removeProtocolIfEmpty:"],
 referencedClasses: ["SystemAnnouncer", "MethodMoved"]
 }),
 smalltalk.CompiledMethod);

+ 1 - 1
st/Helios-Inspector.st

@@ -25,7 +25,7 @@ renderContentOn: html
 selectionDisplayString
 	|selection|
 	selection := model selection.
-    ^ (model variables keys includes: selection)
+    ^ (model variables includesKey: selection)
     	ifTrue:[ (model instVarObjectAt: selection) printString ]
       	ifFalse:[ '' ]
 ! !

+ 4 - 5
st/IDE.st

@@ -727,8 +727,7 @@ methods
 		ifNil: [ #() ]
 		ifNotNil: [ klass methodDictionary values ]]
 	ifNotNil: [
-		klass methodDictionary values select: [ :each |
-			each protocol = selectedProtocol ]]) 
+		klass methodsInProtocol: selectedProtocol ]) 
 				sort: [ :a :b | a selector < b selector ]
 !
 
@@ -1721,7 +1720,7 @@ updateValueTextarea
 
 updateVariablesList
 	variablesList contents: [ :html |
-		self variables keys do: [ :each || li |
+		self variables keysDo: [ :each || li |
 			li := html li.
 			li
 				with: each;
@@ -1841,14 +1840,14 @@ searchMethodSource
 	| regex |
 	regex := selector allButFirst.
 	self classesAndMetaclasses do: [ :each |
-		each methodDictionary values do: [ :value |
+		each methodDictionary valuesDo: [ :value |
 			(value source match: regex) ifTrue: [
 				self matches add: value ]] ]
 !
 
 searchReferencedClasses
 	self classesAndMetaclasses do: [ :each |
-		each methodDictionary values do: [ :value |
+		each methodDictionary valuesDo: [ :value |
 			(value referencedClasses includes: selector) ifTrue: [
 				self referencedClasses add: value ]] ]
 !

+ 13 - 11
st/Kernel-Classes.st

@@ -145,7 +145,7 @@ methodsFor: aString stamp: aStamp
 !
 
 methodsInProtocol: aString
-	^ self methodDictionary values select: [ :each | each protocol = aString ]
+	^ self methods select: [ :each | each protocol = aString ]
 !
 
 name
@@ -180,6 +180,12 @@ prototype
 	<return self.fn.prototype>
 !
 
+removeProtocolIfEmpty: aString
+	self methods
+		detect: [ :each | each protocol = aString ]
+		ifNone: [ self organization removeElement: aString ]
+!
+
 selectors
 	^ self methodDictionary keys
 !
@@ -219,9 +225,7 @@ addCompiledMethod: aMethod
 	self basicAddCompiledMethod: aMethod.
 	
 	oldMethod ifNotNil: [
-		(self methods
-			select: [ :each | each protocol = oldMethod protocol ])
-			ifEmpty: [ self organization removeElement: oldMethod protocol ] ].
+		self removeProtocolIfEmpty: oldMethod protocol ].
 	
 	announcement := oldMethod
 		ifNil: [
@@ -257,9 +261,7 @@ recompile
 removeCompiledMethod: aMethod
 	self basicRemoveCompiledMethod: aMethod.
 	
-	self methods
-		detect: [ :each | each protocol = aMethod protocol ]
-		ifNone: [ self organization removeElement: aMethod protocol ].
+	self removeProtocolIfEmpty: aMethod protocol.
 	
 	SystemAnnouncer current
 		announce: (MethodRemoved new
@@ -282,7 +284,7 @@ protocolsDo: aBlock
 
 	| methodsByProtocol |
 	methodsByProtocol := HashedCollection new.
-	self methodDictionary values do: [ :m |
+	self methodDictionary valuesDo: [ :m |
 		(methodsByProtocol at: m protocol ifAbsentPut: [ Array new ])
 			add: m ].
 	self protocols do: [ :protocol |
@@ -312,7 +314,7 @@ basicRemoveCompiledMethod: aMethod
 !Behavior methodsFor: 'testing'!
 
 canUnderstand: aSelector
-	^ (self methodDictionary keys includes: aSelector asString) or: [
+	^ (self includesSelector: aSelector asString) or: [
 		self superclass notNil and: [ self superclass canUnderstand: aSelector ]]
 !
 
@@ -658,12 +660,12 @@ copyClass: aClass to: anotherClass
 
 	anotherClass comment: aClass comment.
 
-	aClass methodDictionary values do: [ :each |
+	aClass methodDictionary valuesDo: [ :each |
 		Compiler new install: each source forClass: anotherClass protocol: each protocol ].
 
 	self basicClass: anotherClass class instanceVariables: aClass class instanceVariableNames.
 
-	aClass class methodDictionary values do: [ :each |
+	aClass class methodDictionary valuesDo: [ :each |
 		Compiler new install: each source forClass: anotherClass class protocol: each protocol ].
 
 	self setupClass: anotherClass

+ 5 - 9
st/Kernel-Collections.st

@@ -1213,15 +1213,11 @@ addFirst: anObject
 !
 
 remove: anObject ifAbsent: aBlock
-	<
-		for(var i=0;i<self.length;i++) {
-			if(_st(self[i]).__eq(anObject)) {
-				self.splice(i,1);
-				return self;
-			}
-		};
-		aBlock._value();
-	>
+	| index |
+	index := self indexOf: anObject ifAbsent: [ 0 ].
+	^ index = 0
+		ifFalse: [ self removeIndex: index. anObject ]
+		ifTrue: [ aBlock value ]
 !
 
 removeAll

+ 2 - 4
st/Kernel-Infrastructure.st

@@ -192,8 +192,7 @@ removeMethod: aMethod
 !
 
 removeProtocol: aString from: aClass
-	(aClass methods
-		select: [ :each | each protocol = aString ])
+	(aClass methodsInProtocol: aString)
 		do: [ :each | aClass removeCompiledMethod: each ]
 !
 
@@ -205,8 +204,7 @@ renameClass: aClass to: aClassName
 !
 
 renameProtocol: aString to: anotherString in: aClass
-	(aClass methods
-		select: [ :each | each protocol = aString ])
+	(aClass methodsInProtocol: aString)
 		do: [ :each | each protocol: anotherString ]
 !
 

+ 3 - 6
st/Kernel-Methods.st

@@ -252,12 +252,9 @@ protocol: aString
 		oldProtocol: oldProtocol;
 		yourself).
 
-	self methodClass ifNotNil: [
-		self methodClass organization addElement: aString.
-	
-		(self methodClass methods
-			select: [ :each | each protocol = oldProtocol ])
-			ifEmpty: [ self methodClass organization removeElement: oldProtocol ] ]
+	self methodClass ifNotNil: [ :methodClass |
+		methodClass organization addElement: aString.
+		methodClass removeProtocolIfEmpty: oldProtocol ]
 !
 
 referencedClasses