Browse Source

Improved announcement support

Nicolas Petton 12 years ago
parent
commit
18c7d1c2d4
5 changed files with 1147 additions and 139 deletions
  1. 414 46
      js/Helios-Browser.deploy.js
  2. 546 63
      js/Helios-Browser.js
  3. 2 2
      js/Helios-Workspace.js
  4. 185 26
      st/Helios-Browser.st
  5. 0 2
      st/Helios-Workspace.st

+ 414 - 46
js/Helios-Browser.deploy.js

@@ -245,6 +245,18 @@ smalltalk.HLBrowser.klass);
 
 
 smalltalk.addClass('HLBrowserListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-Browser');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.HLNavigationListWidget.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLBrowserListWidget)})},
+messageSends: ["initialize", "observeSystem"]}),
+smalltalk.HLBrowserListWidget);
+
 smalltalk.addMethod(
 "_model",
 smalltalk.method({
@@ -280,6 +292,16 @@ return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$
 messageSends: []}),
 smalltalk.HLBrowserListWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLBrowserListWidget)})},
+messageSends: []}),
+smalltalk.HLBrowserListWidget);
+
 
 smalltalk.addMethod(
 "_on_",
@@ -640,12 +662,13 @@ smalltalk.addMethod(
 "_iconForItem_",
 smalltalk.method({
 selector: "iconForItem:",
-fn: function (aCompiledMethod){
+fn: function (aSelector){
 var self=this;
-var override,overriden;
+var override,overriden,method;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-override=_st(self)._isOverride_(aCompiledMethod);
-overriden=_st(self)._isOverridden_(aCompiledMethod);
+method=_st(self)._methodForSelector_(aSelector);
+override=_st(self)._isOverride_(method);
+overriden=_st(self)._isOverridden_(method);
 $2=override;
 if(smalltalk.assert($2)){
 $3=overriden;
@@ -663,8 +686,8 @@ $1="icon-none";
 };
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"iconForItem:",{aCompiledMethod:aCompiledMethod,override:override,overriden:overriden}, smalltalk.HLMethodsListWidget)})},
-messageSends: ["isOverride:", "isOverridden:", "ifTrue:ifFalse:"]}),
+}, function($ctx1) {$ctx1.fill(self,"iconForItem:",{aSelector:aSelector,override:override,overriden:overriden,method:method}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["methodForSelector:", "isOverride:", "isOverridden:", "ifTrue:ifFalse:"]}),
 smalltalk.HLMethodsListWidget);
 
 smalltalk.addMethod(
@@ -705,6 +728,19 @@ return $1;
 messageSends: ["isOverride:", "selectorsCache"]}),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_methodForSelector_",
+smalltalk.method({
+selector: "methodForSelector:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(_st(self)._model())._selectedClass())._methodDictionary())._at_(aSelector);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"methodForSelector:",{aSelector:aSelector}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["at:", "methodDictionary", "selectedClass", "model"]}),
+smalltalk.HLMethodsListWidget);
+
 smalltalk.addMethod(
 "_methodsInProtocol_",
 smalltalk.method({
@@ -742,6 +778,68 @@ return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{}, smalltalk.HLMe
 messageSends: ["on:do:", "onProtocolSelected:", "item", "announcer", "model", "onMethodSelected:"]}),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current();
+_st($1)._on_do_((smalltalk.MethodAdded || MethodAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodAdded_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.MethodRemoved || MethodRemoved),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodRemoved_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["on:do:", "onMethodAdded:", "method", "current", "onMethodRemoved:"]}),
+smalltalk.HLMethodsListWidget);
+
+smalltalk.addMethod(
+"_onMethodAdded_",
+smalltalk.method({
+selector: "onMethodAdded:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+var $early={};
+try {
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+throw $early=[$1];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self)._refresh();
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodAdded:",{aMethod:aMethod}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["detect:ifNone:", "=", "selector", "items", "refresh"]}),
+smalltalk.HLMethodsListWidget);
+
+smalltalk.addMethod(
+"_onMethodRemoved_",
+smalltalk.method({
+selector: "onMethodRemoved:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+var $early={};
+try {
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._selector()).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+throw $early=[$1];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self)._refresh();
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodRemoved:",{aMethod:aMethod}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["detect:ifNone:", "=", "selector", "items", "refresh"]}),
+smalltalk.HLMethodsListWidget);
+
 smalltalk.addMethod(
 "_onMethodSelected_",
 smalltalk.method({
@@ -779,13 +877,13 @@ $4=aString;
 if(($receiver = $4) == nil || $receiver == undefined){
 $2=[];
 } else {
-$2=_st(self)._methodsInProtocol_(aString);
+$2=_st(self)._selectorsInProtocol_(aString);
 };
 };
 _st($1)._items_($2);
 _st(self)._refresh();
 return self}, function($ctx1) {$ctx1.fill(self,"onProtocolSelected:",{aString:aString}, smalltalk.HLMethodsListWidget)})},
-messageSends: ["selectedItem:", "items:", "ifNil:ifNotNil:", "methodsInProtocol:", "selectedClass", "model", "refresh"]}),
+messageSends: ["selectedItem:", "items:", "ifNil:ifNotNil:", "selectorsInProtocol:", "selectedClass", "model", "refresh"]}),
 smalltalk.HLMethodsListWidget);
 
 smalltalk.addMethod(
@@ -854,22 +952,22 @@ smalltalk.addMethod(
 "_renderItemLabel_on_",
 smalltalk.method({
 selector: "renderItemLabel:on:",
-fn: function (aCompiledMethod,html){
+fn: function (aSelector,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(_st(aCompiledMethod)._selector());
-return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aCompiledMethod:aCompiledMethod,html:html}, smalltalk.HLMethodsListWidget)})},
-messageSends: ["with:", "selector"]}),
+return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(aSelector);
+return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aSelector:aSelector,html:html}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["with:"]}),
 smalltalk.HLMethodsListWidget);
 
 smalltalk.addMethod(
 "_selectItem_",
 smalltalk.method({
 selector: "selectItem:",
-fn: function (aCompiledMethod){
+fn: function (aSelector){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._selectedMethod_(aCompiledMethod);
-return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aCompiledMethod:aCompiledMethod}, smalltalk.HLMethodsListWidget)})},
-messageSends: ["selectedMethod:", "model"]}),
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._selectedMethod_(_st(self)._methodForSelector_(aSelector));
+return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aSelector:aSelector}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["selectedMethod:", "methodForSelector:", "model"]}),
 smalltalk.HLMethodsListWidget);
 
 smalltalk.addMethod(
@@ -885,6 +983,21 @@ return $1;
 messageSends: ["selectorsCache", "class"]}),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_selectorsInProtocol_",
+smalltalk.method({
+selector: "selectorsInProtocol:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._methodsInProtocol_(aString))._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._selector();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectorsInProtocol:",{aString:aString}, smalltalk.HLMethodsListWidget)})},
+messageSends: ["collect:", "selector", "methodsInProtocol:"]}),
+smalltalk.HLMethodsListWidget);
+
 
 smalltalk.HLMethodsListWidget.klass.iVarNames = ['selectorsCache'];
 smalltalk.addMethod(
@@ -1144,7 +1257,7 @@ smalltalk.HLProtocolsListWidget);
 
 
 
-smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedMethod', 'showInstance', 'showComment'], 'Helios-Browser');
+smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedSelector', 'showInstance', 'showComment'], 'Helios-Browser');
 smalltalk.addMethod(
 "_allProtocol",
 smalltalk.method({
@@ -1268,11 +1381,16 @@ smalltalk.method({
 selector: "selectedMethod",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@selectedMethod"];
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(self)._selectedClass();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
+$1=_st(_st(_st(self)._selectedClass())._methodDictionary())._at_(self["@selectedSelector"]);
+};
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selectedMethod",{}, smalltalk.HLBrowserModel)})},
-messageSends: []}),
+messageSends: ["ifNotNil:", "at:", "methodDictionary", "selectedClass"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -1281,16 +1399,28 @@ smalltalk.method({
 selector: "selectedMethod:",
 fn: function (aCompiledMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-$1=_st(self["@selectedMethod"]).__eq(aCompiledMethod);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+$1=_st(self["@selectedSelector"]).__eq(aCompiledMethod);
 if(smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-self["@selectedMethod"]=aCompiledMethod;
+$3=aCompiledMethod;
+if(($receiver = $3) == nil || $receiver == undefined){
+self["@selectedSelector"]=nil;
+self["@selectedSelector"];
+} else {
+$4=_st(self["@selectedSelector"]).__eq(_st(aCompiledMethod)._selector());
+if(smalltalk.assert($4)){
+$5=self;
+return $5;
+};
+self["@selectedSelector"]=_st(aCompiledMethod)._selector();
+self["@selectedSelector"];
+};
 _st(_st(self)._announcer())._announce_(_st((smalltalk.HLMethodSelected || HLMethodSelected))._on_(aCompiledMethod));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedMethod:",{aCompiledMethod:aCompiledMethod}, smalltalk.HLBrowserModel)})},
-messageSends: ["ifTrue:", "=", "announce:", "on:", "announcer"]}),
+messageSends: ["ifTrue:", "=", "ifNil:ifNotNil:", "selector", "announce:", "on:", "announcer"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -1449,7 +1579,7 @@ messageSends: ["environment:", "new", "yourself"]}),
 smalltalk.HLBrowserModel.klass);
 
 
-smalltalk.addClass('HLBrowserSourceWidget', smalltalk.HLWidget, ['model', 'codeWidget'], 'Helios-Browser');
+smalltalk.addClass('HLBrowserSourceWidget', smalltalk.HLWidget, ['model', 'methodContents', 'codeWidget'], 'Helios-Browser');
 smalltalk.addMethod(
 "_codeWidget",
 smalltalk.method({
@@ -1476,10 +1606,10 @@ selector: "contents",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st(self)._sourceArea())._contents();
+$1=_st(_st(self)._codeWidget())._contents();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"contents",{}, smalltalk.HLBrowserSourceWidget)})},
-messageSends: ["contents", "sourceArea"]}),
+messageSends: ["contents", "codeWidget"]}),
 smalltalk.HLBrowserSourceWidget);
 
 smalltalk.addMethod(
@@ -1488,9 +1618,65 @@ smalltalk.method({
 selector: "contents:",
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._codeWidget())._contents_(aString);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._methodContents_(aString);
+_st(_st(self)._codeWidget())._contents_(aString);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString}, smalltalk.HLBrowserSourceWidget)})},
-messageSends: ["contents:", "codeWidget"]}),
+messageSends: ["methodContents:", "contents:", "codeWidget"]}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_hasModification",
+smalltalk.method({
+selector: "hasModification",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._methodContents()).__eq(_st(self)._contents()))._not();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"hasModification",{}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["not", "=", "contents", "methodContents"]}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["initialize", "observeSystem"]}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_methodContents",
+smalltalk.method({
+selector: "methodContents",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@methodContents"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@methodContents"]="";
+$1=self["@methodContents"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"methodContents",{}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_methodContents_",
+smalltalk.method({
+selector: "methodContents:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@methodContents"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"methodContents:",{aString:aString}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: []}),
 smalltalk.HLBrowserSourceWidget);
 
 smalltalk.addMethod(
@@ -1537,6 +1723,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{}, smalltalk.HLBr
 messageSends: ["on:do:", "onMethodSelected:", "item", "announcer", "model", "onClassSelected:", "onProtocolSelected:"]}),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current())._on_do_((smalltalk.MethodModified || MethodModified),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodModified_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["on:do:", "onMethodModified:", "method", "current"]}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_onClassSelected_",
 smalltalk.method({
@@ -1556,6 +1755,28 @@ return self}, function($ctx1) {$ctx1.fill(self,"onClassSelected:",{aClass:aClass
 messageSends: ["ifNil:", "contents:", "definition"]}),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_onMethodModified_",
+smalltalk.method({
+selector: "onMethodModified:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=_st(_st(_st(self)._model())._selectedClass()).__eq(_st(aMethod)._methodClass());
+if(! smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+$3=_st(_st(_st(_st(self)._model())._selectedMethod())._selector()).__eq(_st(aMethod)._selector());
+if(! smalltalk.assert($3)){
+$4=self;
+return $4;
+};
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodModified:",{aMethod:aMethod}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["ifFalse:", "=", "methodClass", "selectedClass", "model", "selector", "selectedMethod", "refresh"]}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_onMethodSelected_",
 smalltalk.method({
@@ -1594,6 +1815,24 @@ return self}, function($ctx1) {$ctx1.fill(self,"onProtocolSelected:",{aString:aS
 messageSends: ["ifNil:", "contents:", "selectedClass", "model", "definition"]}),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(self)._hasModification();
+if(smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+_st(self)._contents_(_st(_st(_st(self)._model())._selectedMethod())._source());
+smalltalk.HLWidget.fn.prototype._refresh.apply(_st(self), []);
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{}, smalltalk.HLBrowserSourceWidget)})},
+messageSends: ["ifTrue:", "hasModification", "contents:", "source", "selectedMethod", "model", "refresh"]}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_renderContentOn_",
 smalltalk.method({
@@ -1623,7 +1862,59 @@ messageSends: ["model:", "new", "yourself"]}),
 smalltalk.HLBrowserSourceWidget.klass);
 
 
-smalltalk.addClass('HLClassCache', smalltalk.Object, ['class', 'parentCache', 'overrideCache', 'overriddenCache'], 'Helios-Browser');
+smalltalk.addClass('HLClassCache', smalltalk.Object, ['class', 'selectorsCache', 'overrideCache', 'overriddenCache'], 'Helios-Browser');
+smalltalk.addMethod(
+"_invalidateChildrenSelector_",
+smalltalk.method({
+selector: "invalidateChildrenSelector:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(_st(self)._theClass())._subclasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(self)._selectorsCache())._cacheFor_(each);
+_st($1)._removeSelector_(aSelector);
+$2=_st($1)._invalidateChildrenSelector_(aSelector);
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateChildrenSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+messageSends: ["do:", "removeSelector:", "cacheFor:", "selectorsCache", "invalidateChildrenSelector:", "subclasses", "theClass"]}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_invalidateParentSelector_",
+smalltalk.method({
+selector: "invalidateParentSelector:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=_st(_st(self)._theClass())._superclass();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+$2=_st(_st(self)._selectorsCache())._cacheFor_(_st(_st(self)._theClass())._superclass());
+_st($2)._removeSelector_(aSelector);
+$3=_st($2)._invalidateParentSelector_(aSelector);
+$3;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateParentSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+messageSends: ["ifNotNil:", "removeSelector:", "cacheFor:", "superclass", "theClass", "selectorsCache", "invalidateParentSelector:"]}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_invalidateSelector_",
+smalltalk.method({
+selector: "invalidateSelector:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self;
+_st($1)._invalidateParentSelector_(aSelector);
+_st($1)._invalidateChildrenSelector_(aSelector);
+$2=_st($1)._removeSelector_(aSelector);
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+messageSends: ["invalidateParentSelector:", "invalidateChildrenSelector:", "removeSelector:"]}),
+smalltalk.HLClassCache);
+
 smalltalk.addMethod(
 "_isOverridden_",
 smalltalk.method({
@@ -1693,26 +1984,40 @@ messageSends: ["ifNil:", "new"]}),
 smalltalk.HLClassCache);
 
 smalltalk.addMethod(
-"_parentCache",
+"_removeSelector_",
 smalltalk.method({
-selector: "parentCache",
+selector: "removeSelector:",
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._overriddenCache())._removeKey_ifAbsent_(aSelector,(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(self)._overrideCache())._removeKey_ifAbsent_(aSelector,(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"removeSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+messageSends: ["removeKey:ifAbsent:", "overriddenCache", "overrideCache"]}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_selectorsCache",
+smalltalk.method({
+selector: "selectorsCache",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@parentCache"];
+$1=self["@selectorsCache"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"parentCache",{}, smalltalk.HLClassCache)})},
+}, function($ctx1) {$ctx1.fill(self,"selectorsCache",{}, smalltalk.HLClassCache)})},
 messageSends: []}),
 smalltalk.HLClassCache);
 
 smalltalk.addMethod(
-"_parentCache_",
+"_selectorsCache_",
 smalltalk.method({
-selector: "parentCache:",
+selector: "selectorsCache:",
 fn: function (aCache){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@parentCache"]=aCache;
-return self}, function($ctx1) {$ctx1.fill(self,"parentCache:",{aCache:aCache}, smalltalk.HLClassCache)})},
+return smalltalk.withContext(function($ctx1) { 
self["@selectorsCache"]=aCache;
+return self}, function($ctx1) {$ctx1.fill(self,"selectorsCache:",{aCache:aCache}, smalltalk.HLClassCache)})},
 messageSends: []}),
 smalltalk.HLClassCache);
 
@@ -1742,20 +2047,20 @@ smalltalk.HLClassCache);
 
 
 smalltalk.addMethod(
-"_on_parentCache_",
+"_on_selectorsCache_",
 smalltalk.method({
-selector: "on:parentCache:",
-fn: function (aClass,aCache){
+selector: "on:selectorsCache:",
+fn: function (aClass,aSelectorsCache){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(self)._new();
 _st($2)._theClass_(aClass);
-_st($2)._parentCache_(aCache);
+_st($2)._selectorsCache_(aSelectorsCache);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:parentCache:",{aClass:aClass,aCache:aCache}, smalltalk.HLClassCache.klass)})},
-messageSends: ["theClass:", "new", "parentCache:", "yourself"]}),
+}, function($ctx1) {$ctx1.fill(self,"on:selectorsCache:",{aClass:aClass,aSelectorsCache:aSelectorsCache}, smalltalk.HLClassCache.klass)})},
+messageSends: ["theClass:", "new", "selectorsCache:", "yourself"]}),
 smalltalk.HLClassCache.klass);
 
 
@@ -1800,6 +2105,29 @@ return $1;
 messageSends: ["ifNil:", "new"]}),
 smalltalk.HLSelectorsCache);
 
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLSelectorsCache)})},
+messageSends: ["initialize", "observeSystem"]}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_invalidateCacheFor_",
+smalltalk.method({
+selector: "invalidateCacheFor:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._cacheFor_(_st(aMethod)._methodClass()))._invalidateSelector_(_st(aMethod)._selector());
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateCacheFor:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+messageSends: ["invalidateSelector:", "selector", "cacheFor:", "methodClass"]}),
+smalltalk.HLSelectorsCache);
+
 smalltalk.addMethod(
 "_isOverridden_",
 smalltalk.method({
@@ -1833,10 +2161,50 @@ selector: "newCacheFor:",
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st((smalltalk.HLClassCache || HLClassCache))._on_parentCache_(aClass,_st(self)._cacheFor_(_st(aClass)._superclass()));
+$1=_st((smalltalk.HLClassCache || HLClassCache))._on_selectorsCache_(aClass,self);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"newCacheFor:",{aClass:aClass}, smalltalk.HLSelectorsCache)})},
-messageSends: ["on:parentCache:", "cacheFor:", "superclass"]}),
+messageSends: ["on:selectorsCache:"]}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current();
+_st($1)._on_do_((smalltalk.MethodAdded || MethodAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodAdded_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.MethodRemoved || MethodRemoved),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodRemoved_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLSelectorsCache)})},
+messageSends: ["on:do:", "onMethodAdded:", "method", "current", "onMethodRemoved:"]}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_onMethodAdded_",
+smalltalk.method({
+selector: "onMethodAdded:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._invalidateCacheFor_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodAdded:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+messageSends: ["invalidateCacheFor:"]}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_onMethodRemoved_",
+smalltalk.method({
+selector: "onMethodRemoved:",
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._invalidateCacheFor_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodRemoved:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+messageSends: ["invalidateCacheFor:"]}),
 smalltalk.HLSelectorsCache);
 
 

+ 546 - 63
js/Helios-Browser.js

@@ -320,6 +320,23 @@ smalltalk.HLBrowser.klass);
 
 
 smalltalk.addClass('HLBrowserListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-Browser');
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.HLNavigationListWidget.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLBrowserListWidget)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a    \x0a    self observeSystem",
+messageSends: ["initialize", "observeSystem"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserListWidget);
+
 smalltalk.addMethod(
 "_model",
 smalltalk.method({
@@ -370,6 +387,21 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserListWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLBrowserListWidget)})},
+args: [],
+source: "observeSystem",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserListWidget);
+
 
 smalltalk.addMethod(
 "_on_",
@@ -836,12 +868,13 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "iconForItem:",
 category: 'accessing',
-fn: function (aCompiledMethod){
+fn: function (aSelector){
 var self=this;
-var override,overriden;
+var override,overriden,method;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-override=_st(self)._isOverride_(aCompiledMethod);
-overriden=_st(self)._isOverridden_(aCompiledMethod);
+method=_st(self)._methodForSelector_(aSelector);
+override=_st(self)._isOverride_(method);
+overriden=_st(self)._isOverridden_(method);
 $2=override;
 if(smalltalk.assert($2)){
 $3=overriden;
@@ -859,10 +892,10 @@ $1="icon-none";
 };
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"iconForItem:",{aCompiledMethod:aCompiledMethod,override:override,overriden:overriden}, smalltalk.HLMethodsListWidget)})},
-args: ["aCompiledMethod"],
-source: "iconForItem: aCompiledMethod\x0a\x09| override overriden |\x0a    \x0a    override := self isOverride: aCompiledMethod.\x0a    overriden := self isOverridden: aCompiledMethod.\x0a    \x0a\x09^ override\x0a    \x09ifTrue: [ overriden\x0a\x09\x09\x09ifTrue: [ 'icon-resize-vertical' ]\x0a\x09\x09\x09ifFalse: [ 'icon-arrow-up' ] ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09overriden\x0a\x09\x09\x09ifTrue: [ 'icon-arrow-down' ]\x0a\x09\x09\x09ifFalse: [ 'icon-none' ] ]",
-messageSends: ["isOverride:", "isOverridden:", "ifTrue:ifFalse:"],
+}, function($ctx1) {$ctx1.fill(self,"iconForItem:",{aSelector:aSelector,override:override,overriden:overriden,method:method}, smalltalk.HLMethodsListWidget)})},
+args: ["aSelector"],
+source: "iconForItem: aSelector\x0a\x09| override overriden method |\x0a    \x0a    method := self methodForSelector: aSelector.\x0a    override := self isOverride: method.\x0a    overriden := self isOverridden: method.\x0a    \x0a\x09^ override\x0a    \x09ifTrue: [ overriden\x0a\x09\x09\x09ifTrue: [ 'icon-resize-vertical' ]\x0a\x09\x09\x09ifFalse: [ 'icon-arrow-up' ] ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09overriden\x0a\x09\x09\x09ifTrue: [ 'icon-arrow-down' ]\x0a\x09\x09\x09ifFalse: [ 'icon-none' ] ]",
+messageSends: ["methodForSelector:", "isOverride:", "isOverridden:", "ifTrue:ifFalse:"],
 referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
@@ -920,6 +953,24 @@ referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_methodForSelector_",
+smalltalk.method({
+selector: "methodForSelector:",
+category: 'accessing',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(_st(self)._model())._selectedClass())._methodDictionary())._at_(aSelector);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"methodForSelector:",{aSelector:aSelector}, smalltalk.HLMethodsListWidget)})},
+args: ["aSelector"],
+source: "methodForSelector: aSelector\x0a\x09^ self model selectedClass\x0a    \x09methodDictionary at: aSelector",
+messageSends: ["at:", "methodDictionary", "selectedClass", "model"],
+referencedClasses: []
+}),
+smalltalk.HLMethodsListWidget);
+
 smalltalk.addMethod(
 "_methodsInProtocol_",
 smalltalk.method({
@@ -967,6 +1018,83 @@ referencedClasses: ["HLProtocolSelected", "HLShowInstanceToggled", "HLMethodSele
 }),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current();
+_st($1)._on_do_((smalltalk.MethodAdded || MethodAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodAdded_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.MethodRemoved || MethodRemoved),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodRemoved_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLMethodsListWidget)})},
+args: [],
+source: "observeSystem\x0a\x09SystemAnnouncer current \x0a    \x09on: MethodAdded \x0a        do: [ :ann | self onMethodAdded: ann method ];\x0a        on: MethodRemoved \x0a        do: [ :ann | self onMethodRemoved: ann method ]",
+messageSends: ["on:do:", "onMethodAdded:", "method", "current", "onMethodRemoved:"],
+referencedClasses: ["MethodAdded", "SystemAnnouncer", "MethodRemoved"]
+}),
+smalltalk.HLMethodsListWidget);
+
+smalltalk.addMethod(
+"_onMethodAdded_",
+smalltalk.method({
+selector: "onMethodAdded:",
+category: 'reactions',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+var $early={};
+try {
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+throw $early=[$1];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self)._refresh();
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodAdded:",{aMethod:aMethod}, smalltalk.HLMethodsListWidget)})},
+args: ["aMethod"],
+source: "onMethodAdded: aMethod\x0a\x09self items detect: [ :each | each = aMethod selector ] ifNone: [ ^ self ].\x0a    \x0a    self refresh",
+messageSends: ["detect:ifNone:", "=", "selector", "items", "refresh"],
+referencedClasses: []
+}),
+smalltalk.HLMethodsListWidget);
+
+smalltalk.addMethod(
+"_onMethodRemoved_",
+smalltalk.method({
+selector: "onMethodRemoved:",
+category: 'reactions',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+var $early={};
+try {
+_st(_st(self)._items())._detect_ifNone_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._selector()).__eq(_st(aMethod)._selector());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
$1=self;
+throw $early=[$1];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self)._refresh();
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"onMethodRemoved:",{aMethod:aMethod}, smalltalk.HLMethodsListWidget)})},
+args: ["aMethod"],
+source: "onMethodRemoved: aMethod\x0a\x09self items detect: [ :each | each selector = aMethod selector ] ifNone: [ ^ self ].\x0a    \x0a    self refresh",
+messageSends: ["detect:ifNone:", "=", "selector", "items", "refresh"],
+referencedClasses: []
+}),
+smalltalk.HLMethodsListWidget);
+
 smalltalk.addMethod(
 "_onMethodSelected_",
 smalltalk.method({
@@ -1010,15 +1138,15 @@ $4=aString;
 if(($receiver = $4) == nil || $receiver == undefined){
 $2=[];
 } else {
-$2=_st(self)._methodsInProtocol_(aString);
+$2=_st(self)._selectorsInProtocol_(aString);
 };
 };
 _st($1)._items_($2);
 _st(self)._refresh();
 return self}, function($ctx1) {$ctx1.fill(self,"onProtocolSelected:",{aString:aString}, smalltalk.HLMethodsListWidget)})},
 args: ["aString"],
-source: "onProtocolSelected: aString\x0a    self selectedItem: nil.\x0a    \x0a    self items: (self model selectedClass \x0a    \x09ifNil: [ #() ]\x0a      \x09ifNotNil: [ aString\x0a    \x09\x09ifNil: [ #() ]\x0a      \x09\x09ifNotNil: [ self methodsInProtocol: aString ] ]).\x0a        \x0a    self refresh",
-messageSends: ["selectedItem:", "items:", "ifNil:ifNotNil:", "methodsInProtocol:", "selectedClass", "model", "refresh"],
+source: "onProtocolSelected: aString\x0a    self selectedItem: nil.\x0a    \x0a    self items: (self model selectedClass \x0a    \x09ifNil: [ #() ]\x0a      \x09ifNotNil: [ aString\x0a    \x09\x09ifNil: [ #() ]\x0a      \x09\x09ifNotNil: [ self selectorsInProtocol: aString ] ]).\x0a        \x0a    self refresh",
+messageSends: ["selectedItem:", "items:", "ifNil:ifNotNil:", "selectorsInProtocol:", "selectedClass", "model", "refresh"],
 referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
@@ -1094,7 +1222,7 @@ $3;
 };
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html}, smalltalk.HLMethodsListWidget)})},
 args: ["html"],
-source: "renderContentOn: html\x0a\x09self model showInstance\x0a    \x09ifFalse: [ html div \x0a        \x09class: 'class_side'; \x0a            with: [ super renderContentOn: html ] ]\x0a      \x09ifTrue: [ super renderContentOn: html ].\x0a        \x0a    \x22self flushSelectorsCache\x22",
+source: "renderContentOn: html\x0a\x09self model showInstance\x0a    \x09ifFalse: [ html div \x0a        \x09class: 'class_side'; \x0a            with: [ super renderContentOn: html ] ]\x0a      \x09ifTrue: [ super renderContentOn: html ]",
 messageSends: ["ifFalse:ifTrue:", "class:", "div", "with:", "renderContentOn:", "showInstance", "model"],
 referencedClasses: []
 }),
@@ -1105,13 +1233,13 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "renderItemLabel:on:",
 category: 'rendering',
-fn: function (aCompiledMethod,html){
+fn: function (aSelector,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(_st(aCompiledMethod)._selector());
-return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aCompiledMethod:aCompiledMethod,html:html}, smalltalk.HLMethodsListWidget)})},
-args: ["aCompiledMethod", "html"],
-source: "renderItemLabel: aCompiledMethod on: html\x0a\x09html with: aCompiledMethod selector",
-messageSends: ["with:", "selector"],
+return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(aSelector);
+return self}, function($ctx1) {$ctx1.fill(self,"renderItemLabel:on:",{aSelector:aSelector,html:html}, smalltalk.HLMethodsListWidget)})},
+args: ["aSelector", "html"],
+source: "renderItemLabel: aSelector on: html\x0a\x09html with: aSelector",
+messageSends: ["with:"],
 referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
@@ -1121,13 +1249,13 @@ smalltalk.addMethod(
 smalltalk.method({
 selector: "selectItem:",
 category: 'actions',
-fn: function (aCompiledMethod){
+fn: function (aSelector){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._selectedMethod_(aCompiledMethod);
-return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aCompiledMethod:aCompiledMethod}, smalltalk.HLMethodsListWidget)})},
-args: ["aCompiledMethod"],
-source: "selectItem: aCompiledMethod\x0a   \x09self model selectedMethod: aCompiledMethod",
-messageSends: ["selectedMethod:", "model"],
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._model())._selectedMethod_(_st(self)._methodForSelector_(aSelector));
+return self}, function($ctx1) {$ctx1.fill(self,"selectItem:",{aSelector:aSelector}, smalltalk.HLMethodsListWidget)})},
+args: ["aSelector"],
+source: "selectItem: aSelector\x0a   \x09self model selectedMethod: (self methodForSelector: aSelector)\x0a    ",
+messageSends: ["selectedMethod:", "methodForSelector:", "model"],
 referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
@@ -1150,6 +1278,26 @@ referencedClasses: []
 }),
 smalltalk.HLMethodsListWidget);
 
+smalltalk.addMethod(
+"_selectorsInProtocol_",
+smalltalk.method({
+selector: "selectorsInProtocol:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._methodsInProtocol_(aString))._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._selector();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectorsInProtocol:",{aString:aString}, smalltalk.HLMethodsListWidget)})},
+args: ["aString"],
+source: "selectorsInProtocol: aString\x0a\x09^ (self methodsInProtocol: aString)\x0a    \x09collect: [ :each | each selector ]",
+messageSends: ["collect:", "selector", "methodsInProtocol:"],
+referencedClasses: []
+}),
+smalltalk.HLMethodsListWidget);
+
 
 smalltalk.HLMethodsListWidget.klass.iVarNames = ['selectorsCache'];
 smalltalk.addMethod(
@@ -1484,7 +1632,7 @@ smalltalk.HLProtocolsListWidget);
 
 
 
-smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedMethod', 'showInstance', 'showComment'], 'Helios-Browser');
+smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedSelector', 'showInstance', 'showComment'], 'Helios-Browser');
 smalltalk.addMethod(
 "_allProtocol",
 smalltalk.method({
@@ -1644,13 +1792,18 @@ selector: "selectedMethod",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@selectedMethod"];
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=_st(self)._selectedClass();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
+$1=_st(_st(_st(self)._selectedClass())._methodDictionary())._at_(self["@selectedSelector"]);
+};
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selectedMethod",{}, smalltalk.HLBrowserModel)})},
 args: [],
-source: "selectedMethod\x0a\x09^ selectedMethod",
-messageSends: [],
+source: "selectedMethod\x0a\x09^ self selectedClass\x0a    \x09ifNotNil: [ self selectedClass methodDictionary at: selectedSelector ]",
+messageSends: ["ifNotNil:", "at:", "methodDictionary", "selectedClass"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
@@ -1662,18 +1815,30 @@ selector: "selectedMethod:",
 category: 'accessing',
 fn: function (aCompiledMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-$1=_st(self["@selectedMethod"]).__eq(aCompiledMethod);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
+$1=_st(self["@selectedSelector"]).__eq(aCompiledMethod);
 if(smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-self["@selectedMethod"]=aCompiledMethod;
+$3=aCompiledMethod;
+if(($receiver = $3) == nil || $receiver == undefined){
+self["@selectedSelector"]=nil;
+self["@selectedSelector"];
+} else {
+$4=_st(self["@selectedSelector"]).__eq(_st(aCompiledMethod)._selector());
+if(smalltalk.assert($4)){
+$5=self;
+return $5;
+};
+self["@selectedSelector"]=_st(aCompiledMethod)._selector();
+self["@selectedSelector"];
+};
 _st(_st(self)._announcer())._announce_(_st((smalltalk.HLMethodSelected || HLMethodSelected))._on_(aCompiledMethod));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedMethod:",{aCompiledMethod:aCompiledMethod}, smalltalk.HLBrowserModel)})},
 args: ["aCompiledMethod"],
-source: "selectedMethod: aCompiledMethod\x0a\x09selectedMethod = aCompiledMethod ifTrue: [ ^ self ].\x0a\x0a\x09selectedMethod := aCompiledMethod.    \x0a    self announcer announce: (HLMethodSelected on: aCompiledMethod)",
-messageSends: ["ifTrue:", "=", "announce:", "on:", "announcer"],
+source: "selectedMethod: aCompiledMethod\x0a\x09selectedSelector = aCompiledMethod ifTrue: [ ^ self ].\x0a    \x0a    aCompiledMethod\x0a    \x09ifNil: [ selectedSelector := nil ]\x0a      \x09ifNotNil: [\x0a\x09\x09\x09selectedSelector = aCompiledMethod selector ifTrue: [ ^ self ].\x0a\x09\x09\x09selectedSelector := aCompiledMethod selector ].\x0a\x0a    self announcer announce: (HLMethodSelected on: aCompiledMethod)",
+messageSends: ["ifTrue:", "=", "ifNil:ifNotNil:", "selector", "announce:", "on:", "announcer"],
 referencedClasses: ["HLMethodSelected"]
 }),
 smalltalk.HLBrowserModel);
@@ -1879,7 +2044,7 @@ referencedClasses: []
 smalltalk.HLBrowserModel.klass);
 
 
-smalltalk.addClass('HLBrowserSourceWidget', smalltalk.HLWidget, ['model', 'codeWidget'], 'Helios-Browser');
+smalltalk.addClass('HLBrowserSourceWidget', smalltalk.HLWidget, ['model', 'methodContents', 'codeWidget'], 'Helios-Browser');
 smalltalk.addMethod(
 "_codeWidget",
 smalltalk.method({
@@ -1912,12 +2077,12 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(_st(self)._sourceArea())._contents();
+$1=_st(_st(self)._codeWidget())._contents();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"contents",{}, smalltalk.HLBrowserSourceWidget)})},
 args: [],
-source: "contents\x0a\x09^ self sourceArea contents",
-messageSends: ["contents", "sourceArea"],
+source: "contents\x0a\x09^ self codeWidget contents",
+messageSends: ["contents", "codeWidget"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserSourceWidget);
@@ -1929,11 +2094,87 @@ selector: "contents:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._codeWidget())._contents_(aString);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._methodContents_(aString);
+_st(_st(self)._codeWidget())._contents_(aString);
 return self}, function($ctx1) {$ctx1.fill(self,"contents:",{aString:aString}, smalltalk.HLBrowserSourceWidget)})},
 args: ["aString"],
-source: "contents: aString\x0a\x09self codeWidget contents: aString",
-messageSends: ["contents:", "codeWidget"],
+source: "contents: aString\x0a\x09self methodContents: aString.\x0a\x09self codeWidget contents: aString",
+messageSends: ["methodContents:", "contents:", "codeWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_hasModification",
+smalltalk.method({
+selector: "hasModification",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(_st(self)._methodContents()).__eq(_st(self)._contents()))._not();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"hasModification",{}, smalltalk.HLBrowserSourceWidget)})},
+args: [],
+source: "hasModification\x0a\x09^ (self methodContents = self contents) not",
+messageSends: ["not", "=", "contents", "methodContents"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.HLWidget.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLBrowserSourceWidget)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a    \x0a    self observeSystem",
+messageSends: ["initialize", "observeSystem"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_methodContents",
+smalltalk.method({
+selector: "methodContents",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@methodContents"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@methodContents"]="";
+$1=self["@methodContents"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"methodContents",{}, smalltalk.HLBrowserSourceWidget)})},
+args: [],
+source: "methodContents\x0a\x09^ methodContents ifNil: [ methodContents := '' ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
+smalltalk.addMethod(
+"_methodContents_",
+smalltalk.method({
+selector: "methodContents:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@methodContents"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"methodContents:",{aString:aString}, smalltalk.HLBrowserSourceWidget)})},
+args: ["aString"],
+source: "methodContents: aString\x0a\x09methodContents := aString",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.HLBrowserSourceWidget);
@@ -1997,6 +2238,24 @@ referencedClasses: ["HLMethodSelected", "HLClassSelected", "HLProtocolSelected"]
 }),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current())._on_do_((smalltalk.MethodModified || MethodModified),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodModified_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLBrowserSourceWidget)})},
+args: [],
+source: "observeSystem\x0a\x09SystemAnnouncer current\x0a    \x09on: MethodModified\x0a        do: [ :ann | self onMethodModified: ann method ]",
+messageSends: ["on:do:", "onMethodModified:", "method", "current"],
+referencedClasses: ["MethodModified", "SystemAnnouncer"]
+}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_onClassSelected_",
 smalltalk.method({
@@ -2021,6 +2280,33 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_onMethodModified_",
+smalltalk.method({
+selector: "onMethodModified:",
+category: 'reactions',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+$1=_st(_st(_st(self)._model())._selectedClass()).__eq(_st(aMethod)._methodClass());
+if(! smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+$3=_st(_st(_st(_st(self)._model())._selectedMethod())._selector()).__eq(_st(aMethod)._selector());
+if(! smalltalk.assert($3)){
+$4=self;
+return $4;
+};
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodModified:",{aMethod:aMethod}, smalltalk.HLBrowserSourceWidget)})},
+args: ["aMethod"],
+source: "onMethodModified: aMethod\x0a\x09self model selectedClass = aMethod methodClass ifFalse: [ ^ self ].\x0a    self model selectedMethod selector = aMethod selector ifFalse: [ ^ self ].\x0a\x0a    self refresh",
+messageSends: ["ifFalse:", "=", "methodClass", "selectedClass", "model", "selector", "selectedMethod", "refresh"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_onMethodSelected_",
 smalltalk.method({
@@ -2069,6 +2355,29 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserSourceWidget);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+category: 'updating',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(self)._hasModification();
+if(smalltalk.assert($1)){
+$2=self;
+return $2;
+};
+_st(self)._contents_(_st(_st(_st(self)._model())._selectedMethod())._source());
+smalltalk.HLWidget.fn.prototype._refresh.apply(_st(self), []);
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{}, smalltalk.HLBrowserSourceWidget)})},
+args: [],
+source: "refresh\x0a\x09self hasModification ifTrue: [ ^ self ].\x0a    \x0a\x09self contents: self model selectedMethod source.\x0a    super refresh",
+messageSends: ["ifTrue:", "hasModification", "contents:", "source", "selectedMethod", "model", "refresh"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserSourceWidget);
+
 smalltalk.addMethod(
 "_renderContentOn_",
 smalltalk.method({
@@ -2108,7 +2417,74 @@ referencedClasses: []
 smalltalk.HLBrowserSourceWidget.klass);
 
 
-smalltalk.addClass('HLClassCache', smalltalk.Object, ['class', 'parentCache', 'overrideCache', 'overriddenCache'], 'Helios-Browser');
+smalltalk.addClass('HLClassCache', smalltalk.Object, ['class', 'selectorsCache', 'overrideCache', 'overriddenCache'], 'Helios-Browser');
+smalltalk.addMethod(
+"_invalidateChildrenSelector_",
+smalltalk.method({
+selector: "invalidateChildrenSelector:",
+category: 'actions',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(_st(self)._theClass())._subclasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
$1=_st(_st(self)._selectorsCache())._cacheFor_(each);
+_st($1)._removeSelector_(aSelector);
+$2=_st($1)._invalidateChildrenSelector_(aSelector);
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateChildrenSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+args: ["aSelector"],
+source: "invalidateChildrenSelector: aSelector\x0a\x09self theClass subclasses do: [ :each |\x0a    \x09(self selectorsCache cacheFor: each)\x0a        \x09removeSelector: aSelector;\x0a        \x09invalidateChildrenSelector: aSelector ]",
+messageSends: ["do:", "removeSelector:", "cacheFor:", "selectorsCache", "invalidateChildrenSelector:", "subclasses", "theClass"],
+referencedClasses: []
+}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_invalidateParentSelector_",
+smalltalk.method({
+selector: "invalidateParentSelector:",
+category: 'actions',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+$1=_st(_st(self)._theClass())._superclass();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+$2=_st(_st(self)._selectorsCache())._cacheFor_(_st(_st(self)._theClass())._superclass());
+_st($2)._removeSelector_(aSelector);
+$3=_st($2)._invalidateParentSelector_(aSelector);
+$3;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateParentSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+args: ["aSelector"],
+source: "invalidateParentSelector: aSelector\x0a\x09self theClass superclass ifNotNil: [\x0a    \x09(self selectorsCache cacheFor: self theClass superclass)\x0a        \x09removeSelector: aSelector;\x0a\x09\x09\x09invalidateParentSelector: aSelector ]",
+messageSends: ["ifNotNil:", "removeSelector:", "cacheFor:", "superclass", "theClass", "selectorsCache", "invalidateParentSelector:"],
+referencedClasses: []
+}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_invalidateSelector_",
+smalltalk.method({
+selector: "invalidateSelector:",
+category: 'actions',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self;
+_st($1)._invalidateParentSelector_(aSelector);
+_st($1)._invalidateChildrenSelector_(aSelector);
+$2=_st($1)._removeSelector_(aSelector);
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+args: ["aSelector"],
+source: "invalidateSelector: aSelector\x0a\x09self \x0a    \x09invalidateParentSelector: aSelector;\x0a        invalidateChildrenSelector: aSelector;\x0a        removeSelector: aSelector",
+messageSends: ["invalidateParentSelector:", "invalidateChildrenSelector:", "removeSelector:"],
+referencedClasses: []
+}),
+smalltalk.HLClassCache);
+
 smalltalk.addMethod(
 "_isOverridden_",
 smalltalk.method({
@@ -2198,34 +2574,53 @@ referencedClasses: ["HashedCollection"]
 smalltalk.HLClassCache);
 
 smalltalk.addMethod(
-"_parentCache",
+"_removeSelector_",
 smalltalk.method({
-selector: "parentCache",
+selector: "removeSelector:",
+category: 'private',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._overriddenCache())._removeKey_ifAbsent_(aSelector,(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(self)._overrideCache())._removeKey_ifAbsent_(aSelector,(function(){
+return smalltalk.withContext(function($ctx2) {
}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"removeSelector:",{aSelector:aSelector}, smalltalk.HLClassCache)})},
+args: ["aSelector"],
+source: "removeSelector: aSelector\x0a\x09self overriddenCache \x0a    \x09removeKey: aSelector\x0a        ifAbsent: [ ].\x0a    self overrideCache \x0a    \x09removeKey: aSelector\x0a        ifAbsent: [ ]",
+messageSends: ["removeKey:ifAbsent:", "overriddenCache", "overrideCache"],
+referencedClasses: []
+}),
+smalltalk.HLClassCache);
+
+smalltalk.addMethod(
+"_selectorsCache",
+smalltalk.method({
+selector: "selectorsCache",
 category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=self["@parentCache"];
+$1=self["@selectorsCache"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"parentCache",{}, smalltalk.HLClassCache)})},
+}, function($ctx1) {$ctx1.fill(self,"selectorsCache",{}, smalltalk.HLClassCache)})},
 args: [],
-source: "parentCache\x0a\x09^ parentCache",
+source: "selectorsCache\x0a\x09^ selectorsCache",
 messageSends: [],
 referencedClasses: []
 }),
 smalltalk.HLClassCache);
 
 smalltalk.addMethod(
-"_parentCache_",
+"_selectorsCache_",
 smalltalk.method({
-selector: "parentCache:",
+selector: "selectorsCache:",
 category: 'accessing',
 fn: function (aCache){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@parentCache"]=aCache;
-return self}, function($ctx1) {$ctx1.fill(self,"parentCache:",{aCache:aCache}, smalltalk.HLClassCache)})},
+return smalltalk.withContext(function($ctx1) { 
self["@selectorsCache"]=aCache;
+return self}, function($ctx1) {$ctx1.fill(self,"selectorsCache:",{aCache:aCache}, smalltalk.HLClassCache)})},
 args: ["aCache"],
-source: "parentCache: aCache\x0a\x09parentCache := aCache",
+source: "selectorsCache: aCache\x0a\x09selectorsCache := aCache",
 messageSends: [],
 referencedClasses: []
 }),
@@ -2267,23 +2662,23 @@ smalltalk.HLClassCache);
 
 
 smalltalk.addMethod(
-"_on_parentCache_",
+"_on_selectorsCache_",
 smalltalk.method({
-selector: "on:parentCache:",
+selector: "on:selectorsCache:",
 category: 'instance creation',
-fn: function (aClass,aCache){
+fn: function (aClass,aSelectorsCache){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(self)._new();
 _st($2)._theClass_(aClass);
-_st($2)._parentCache_(aCache);
+_st($2)._selectorsCache_(aSelectorsCache);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:parentCache:",{aClass:aClass,aCache:aCache}, smalltalk.HLClassCache.klass)})},
-args: ["aClass", "aCache"],
-source: "on: aClass parentCache: aCache\x0a\x09^ self new\x0a    \x09theClass: aClass;\x0a        parentCache: aCache;\x0a        yourself",
-messageSends: ["theClass:", "new", "parentCache:", "yourself"],
+}, function($ctx1) {$ctx1.fill(self,"on:selectorsCache:",{aClass:aClass,aSelectorsCache:aSelectorsCache}, smalltalk.HLClassCache.klass)})},
+args: ["aClass", "aSelectorsCache"],
+source: "on: aClass selectorsCache: aSelectorsCache\x0a\x09^ self new\x0a    \x09theClass: aClass;\x0a        selectorsCache: aSelectorsCache;\x0a        yourself",
+messageSends: ["theClass:", "new", "selectorsCache:", "yourself"],
 referencedClasses: []
 }),
 smalltalk.HLClassCache.klass);
@@ -2340,6 +2735,39 @@ referencedClasses: ["HashedCollection"]
 }),
 smalltalk.HLSelectorsCache);
 
+smalltalk.addMethod(
+"_initialize",
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+_st(self)._observeSystem();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{}, smalltalk.HLSelectorsCache)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a    self observeSystem",
+messageSends: ["initialize", "observeSystem"],
+referencedClasses: []
+}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_invalidateCacheFor_",
+smalltalk.method({
+selector: "invalidateCacheFor:",
+category: 'private',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._cacheFor_(_st(aMethod)._methodClass()))._invalidateSelector_(_st(aMethod)._selector());
+return self}, function($ctx1) {$ctx1.fill(self,"invalidateCacheFor:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+args: ["aMethod"],
+source: "invalidateCacheFor: aMethod\x0a\x09(self cacheFor: aMethod methodClass)\x0a    \x09invalidateSelector: aMethod selector",
+messageSends: ["invalidateSelector:", "selector", "cacheFor:", "methodClass"],
+referencedClasses: []
+}),
+smalltalk.HLSelectorsCache);
+
 smalltalk.addMethod(
 "_isOverridden_",
 smalltalk.method({
@@ -2384,16 +2812,71 @@ category: 'factory',
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st((smalltalk.HLClassCache || HLClassCache))._on_parentCache_(aClass,_st(self)._cacheFor_(_st(aClass)._superclass()));
+$1=_st((smalltalk.HLClassCache || HLClassCache))._on_selectorsCache_(aClass,self);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"newCacheFor:",{aClass:aClass}, smalltalk.HLSelectorsCache)})},
 args: ["aClass"],
-source: "newCacheFor: aClass\x0a\x09^ HLClassCache \x0a    \x09on: aClass\x0a        parentCache: (self cacheFor: aClass superclass)",
-messageSends: ["on:parentCache:", "cacheFor:", "superclass"],
+source: "newCacheFor: aClass\x0a\x09^ HLClassCache \x0a    \x09on: aClass\x0a        selectorsCache: self",
+messageSends: ["on:selectorsCache:"],
 referencedClasses: ["HLClassCache"]
 }),
 smalltalk.HLSelectorsCache);
 
+smalltalk.addMethod(
+"_observeSystem",
+smalltalk.method({
+selector: "observeSystem",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.SystemAnnouncer || SystemAnnouncer))._current();
+_st($1)._on_do_((smalltalk.MethodAdded || MethodAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodAdded_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.MethodRemoved || MethodRemoved),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onMethodRemoved_(_st(ann)._method());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeSystem",{}, smalltalk.HLSelectorsCache)})},
+args: [],
+source: "observeSystem\x0a\x09SystemAnnouncer current\x0a\x09\x09on: MethodAdded\x0a        do: [ :ann | self onMethodAdded: ann method ];\x0a        on: MethodRemoved\x0a        do: [ :ann | self onMethodRemoved: ann method ]",
+messageSends: ["on:do:", "onMethodAdded:", "method", "current", "onMethodRemoved:"],
+referencedClasses: ["MethodAdded", "SystemAnnouncer", "MethodRemoved"]
+}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_onMethodAdded_",
+smalltalk.method({
+selector: "onMethodAdded:",
+category: 'reactions',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._invalidateCacheFor_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodAdded:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+args: ["aMethod"],
+source: "onMethodAdded: aMethod\x0a\x09self invalidateCacheFor: aMethod",
+messageSends: ["invalidateCacheFor:"],
+referencedClasses: []
+}),
+smalltalk.HLSelectorsCache);
+
+smalltalk.addMethod(
+"_onMethodRemoved_",
+smalltalk.method({
+selector: "onMethodRemoved:",
+category: 'reactions',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._invalidateCacheFor_(aMethod);
+return self}, function($ctx1) {$ctx1.fill(self,"onMethodRemoved:",{aMethod:aMethod}, smalltalk.HLSelectorsCache)})},
+args: ["aMethod"],
+source: "onMethodRemoved: aMethod\x0a\x09self invalidateCacheFor: aMethod",
+messageSends: ["invalidateCacheFor:"],
+referencedClasses: []
+}),
+smalltalk.HLSelectorsCache);
+
 
 smalltalk.HLSelectorsCache.klass.iVarNames = ['current'];
 smalltalk.addMethod(

+ 2 - 2
js/Helios-Workspace.js

@@ -357,7 +357,7 @@ newInspector=_st(self)._makeInspectorOn_(_st(self)._doIt());
 _st(newInspector)._open();
 return self}, function($ctx1) {$ctx1.fill(self,"inspectIt",{newInspector:newInspector}, smalltalk.HLCodeWidget)})},
 args: [],
-source: "inspectIt\x0a\x0a\x09| newInspector |\x0a       \x0a\x09self announcer announce: (HLInspectItRequested on: model).\x0a\x09newInspector := self makeInspectorOn: self doIt.\x0a\x09newInspector open",
+source: "inspectIt\x0a\x09| newInspector |\x0a       \x0a\x09self announcer announce: (HLInspectItRequested on: model).\x0a\x09newInspector := self makeInspectorOn: self doIt.\x0a\x09newInspector open",
 messageSends: ["announce:", "on:", "announcer", "makeInspectorOn:", "doIt", "open"],
 referencedClasses: ["HLInspectItRequested"]
 }),
@@ -561,7 +561,7 @@ _st(self)._print_(_st(result)._printString());
 _st(self)._focus();
 return self}, function($ctx1) {$ctx1.fill(self,"printIt",{result:result}, smalltalk.HLCodeWidget)})},
 args: [],
-source: "printIt\x0a\x0a\x09| result |\x0a\x0a\x09result:=  self doIt.\x0a       \x0a\x09self announcer announce: (HLPrintItRequested on: model).\x0a\x0a    self print: result printString.\x0a\x09self focus.",
+source: "printIt\x0a\x09| result |\x0a\x0a\x09result:=  self doIt.\x0a       \x0a\x09self announcer announce: (HLPrintItRequested on: model).\x0a\x0a    self print: result printString.\x0a\x09self focus.",
 messageSends: ["doIt", "announce:", "on:", "announcer", "print:", "printString", "focus"],
 referencedClasses: ["HLPrintItRequested"]
 }),

+ 185 - 26
st/Helios-Browser.st

@@ -121,6 +121,17 @@ model: aBrowserModel
 !HLBrowserListWidget methodsFor: 'actions'!
 
 observeModel
+!
+
+observeSystem
+! !
+
+!HLBrowserListWidget methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+    
+    self observeSystem
 ! !
 
 !HLBrowserListWidget class methodsFor: 'instance creation'!
@@ -284,11 +295,12 @@ allProtocol
 	^ self model allProtocol
 !
 
-iconForItem: aCompiledMethod
-	| override overriden |
+iconForItem: aSelector
+	| override overriden method |
     
-    override := self isOverride: aCompiledMethod.
-    overriden := self isOverridden: aCompiledMethod.
+    method := self methodForSelector: aSelector.
+    override := self isOverride: method.
+    overriden := self isOverridden: method.
     
 	^ override
     	ifTrue: [ overriden
@@ -300,6 +312,11 @@ iconForItem: aCompiledMethod
 			ifFalse: [ 'icon-none' ] ]
 !
 
+methodForSelector: aSelector
+	^ self model selectedClass
+    	methodDictionary at: aSelector
+!
+
 methodsInProtocol: aString
 	^ aString = self allProtocol
     	ifTrue: [ self model selectedClass methods ]
@@ -324,6 +341,11 @@ overridenSelectors
 
 selectorsCache
 	^ self class selectorsCache
+!
+
+selectorsInProtocol: aString
+	^ (self methodsInProtocol: aString)
+    	collect: [ :each | each selector ]
 ! !
 
 !HLMethodsListWidget methodsFor: 'actions'!
@@ -337,8 +359,16 @@ observeModel
     	self onMethodSelected: ann item ]
 !
 
-selectItem: aCompiledMethod
-   	self model selectedMethod: aCompiledMethod
+observeSystem
+	SystemAnnouncer current 
+    	on: MethodAdded 
+        do: [ :ann | self onMethodAdded: ann method ];
+        on: MethodRemoved 
+        do: [ :ann | self onMethodRemoved: ann method ]
+!
+
+selectItem: aSelector
+   	self model selectedMethod: (self methodForSelector: aSelector)
 ! !
 
 !HLMethodsListWidget methodsFor: 'cache'!
@@ -356,6 +386,18 @@ initialize
 
 !HLMethodsListWidget methodsFor: 'reactions'!
 
+onMethodAdded: aMethod
+	self items detect: [ :each | each = aMethod selector ] ifNone: [ ^ self ].
+    
+    self refresh
+!
+
+onMethodRemoved: aMethod
+	self items detect: [ :each | each selector = aMethod selector ] ifNone: [ ^ self ].
+    
+    self refresh
+!
+
 onMethodSelected: aMethod
 	self selectedItem: aMethod.
 	aMethod ifNil: [ ^ self ].
@@ -370,7 +412,7 @@ onProtocolSelected: aString
     	ifNil: [ #() ]
       	ifNotNil: [ aString
     		ifNil: [ #() ]
-      		ifNotNil: [ self methodsInProtocol: aString ] ]).
+      		ifNotNil: [ self selectorsInProtocol: aString ] ]).
         
     self refresh
 ! !
@@ -382,13 +424,11 @@ renderContentOn: html
     	ifFalse: [ html div 
         	class: 'class_side'; 
             with: [ super renderContentOn: html ] ]
-      	ifTrue: [ super renderContentOn: html ].
-        
-    "self flushSelectorsCache"
+      	ifTrue: [ super renderContentOn: html ]
 !
 
-renderItemLabel: aCompiledMethod on: html
-	html with: aCompiledMethod selector
+renderItemLabel: aSelector on: html
+	html with: aSelector
 ! !
 
 !HLMethodsListWidget methodsFor: 'testing'!
@@ -531,7 +571,7 @@ renderContentOn: html
 ! !
 
 Object subclass: #HLBrowserModel
-	instanceVariableNames: 'announcer environment selectedPackage selectedClass selectedProtocol selectedMethod showInstance showComment'
+	instanceVariableNames: 'announcer environment selectedPackage selectedClass selectedProtocol selectedSelector showInstance showComment'
 	package: 'Helios-Browser'!
 
 !HLBrowserModel methodsFor: 'accessing'!
@@ -574,13 +614,19 @@ selectedClass: aClass
 !
 
 selectedMethod
-	^ selectedMethod
+	^ self selectedClass
+    	ifNotNil: [ self selectedClass methodDictionary at: selectedSelector ]
 !
 
 selectedMethod: aCompiledMethod
-	selectedMethod = aCompiledMethod ifTrue: [ ^ self ].
+	selectedSelector = aCompiledMethod ifTrue: [ ^ self ].
+    
+    aCompiledMethod
+    	ifNil: [ selectedSelector := nil ]
+      	ifNotNil: [
+			selectedSelector = aCompiledMethod selector ifTrue: [ ^ self ].
+			selectedSelector := aCompiledMethod selector ].
 
-	selectedMethod := aCompiledMethod.    
     self announcer announce: (HLMethodSelected on: aCompiledMethod)
 !
 
@@ -643,7 +689,7 @@ on: anEnvironment
 ! !
 
 HLWidget subclass: #HLBrowserSourceWidget
-	instanceVariableNames: 'model codeWidget'
+	instanceVariableNames: 'model methodContents codeWidget'
 	package: 'Helios-Browser'!
 
 !HLBrowserSourceWidget methodsFor: 'accessing'!
@@ -653,13 +699,22 @@ codeWidget
 !
 
 contents
-	^ self sourceArea contents
+	^ self codeWidget contents
 !
 
 contents: aString
+	self methodContents: aString.
 	self codeWidget contents: aString
 !
 
+methodContents
+	^ methodContents ifNil: [ methodContents := '' ]
+!
+
+methodContents: aString
+	methodContents := aString
+!
+
 model
 	^ model
 !
@@ -679,6 +734,20 @@ observeModel
     	self onClassSelected: ann item ].
     self model announcer on: HLProtocolSelected do: [ :ann |
     	self onProtocolSelected: ann item ]
+!
+
+observeSystem
+	SystemAnnouncer current
+    	on: MethodModified
+        do: [ :ann | self onMethodModified: ann method ]
+! !
+
+!HLBrowserSourceWidget methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+    
+    self observeSystem
 ! !
 
 !HLBrowserSourceWidget methodsFor: 'reactions'!
@@ -689,6 +758,13 @@ onClassSelected: aClass
     self contents: aClass definition
 !
 
+onMethodModified: aMethod
+	self model selectedClass = aMethod methodClass ifFalse: [ ^ self ].
+    self model selectedMethod selector = aMethod selector ifFalse: [ ^ self ].
+
+    self refresh
+!
+
 onMethodSelected: aCompiledMethod
 	aCompiledMethod ifNil: [ ^ self contents: '' ].
     
@@ -707,6 +783,21 @@ renderContentOn: html
 	self codeWidget renderOn: html
 ! !
 
+!HLBrowserSourceWidget methodsFor: 'testing'!
+
+hasModification
+	^ (self methodContents = self contents) not
+! !
+
+!HLBrowserSourceWidget methodsFor: 'updating'!
+
+refresh
+	self hasModification ifTrue: [ ^ self ].
+    
+	self contents: self model selectedMethod source.
+    super refresh
+! !
+
 !HLBrowserSourceWidget class methodsFor: 'instance creation'!
 
 on: aBrowserModel
@@ -716,7 +807,7 @@ on: aBrowserModel
 ! !
 
 Object subclass: #HLClassCache
-	instanceVariableNames: 'class parentCache overrideCache overriddenCache'
+	instanceVariableNames: 'class selectorsCache overrideCache overriddenCache'
 	package: 'Helios-Browser'!
 
 !HLClassCache methodsFor: 'accessing'!
@@ -729,12 +820,12 @@ overrideCache
 	^ overrideCache ifNil: [ overrideCache := HashedCollection new ]
 !
 
-parentCache
-	^ parentCache
+selectorsCache
+	^ selectorsCache
 !
 
-parentCache: aCache
-	parentCache := aCache
+selectorsCache: aCache
+	selectorsCache := aCache
 !
 
 theClass
@@ -745,6 +836,40 @@ theClass: aClass
 	class := aClass
 ! !
 
+!HLClassCache methodsFor: 'actions'!
+
+invalidateChildrenSelector: aSelector
+	self theClass subclasses do: [ :each |
+    	(self selectorsCache cacheFor: each)
+        	removeSelector: aSelector;
+        	invalidateChildrenSelector: aSelector ]
+!
+
+invalidateParentSelector: aSelector
+	self theClass superclass ifNotNil: [
+    	(self selectorsCache cacheFor: self theClass superclass)
+        	removeSelector: aSelector;
+			invalidateParentSelector: aSelector ]
+!
+
+invalidateSelector: aSelector
+	self 
+    	invalidateParentSelector: aSelector;
+        invalidateChildrenSelector: aSelector;
+        removeSelector: aSelector
+! !
+
+!HLClassCache methodsFor: 'private'!
+
+removeSelector: aSelector
+	self overriddenCache 
+    	removeKey: aSelector
+        ifAbsent: [ ].
+    self overrideCache 
+    	removeKey: aSelector
+        ifAbsent: [ ]
+! !
+
 !HLClassCache methodsFor: 'testing'!
 
 isOverridden: aMethod
@@ -761,10 +886,10 @@ isOverride: aMethod
 
 !HLClassCache class methodsFor: 'instance creation'!
 
-on: aClass parentCache: aCache
+on: aClass selectorsCache: aSelectorsCache
 	^ self new
     	theClass: aClass;
-        parentCache: aCache;
+        selectorsCache: aSelectorsCache;
         yourself
 ! !
 
@@ -786,12 +911,46 @@ classesCache
 	^ classesCache ifNil: [ classesCache := HashedCollection new ]
 ! !
 
+!HLSelectorsCache methodsFor: 'actions'!
+
+observeSystem
+	SystemAnnouncer current
+		on: MethodAdded
+        do: [ :ann | self onMethodAdded: ann method ];
+        on: MethodRemoved
+        do: [ :ann | self onMethodRemoved: ann method ]
+! !
+
 !HLSelectorsCache methodsFor: 'factory'!
 
 newCacheFor: aClass
 	^ HLClassCache 
     	on: aClass
-        parentCache: (self cacheFor: aClass superclass)
+        selectorsCache: self
+! !
+
+!HLSelectorsCache methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+    self observeSystem
+! !
+
+!HLSelectorsCache methodsFor: 'private'!
+
+invalidateCacheFor: aMethod
+	(self cacheFor: aMethod methodClass)
+    	invalidateSelector: aMethod selector
+! !
+
+!HLSelectorsCache methodsFor: 'reactions'!
+
+onMethodAdded: aMethod
+	self invalidateCacheFor: aMethod
+!
+
+onMethodRemoved: aMethod
+	self invalidateCacheFor: aMethod
 ! !
 
 !HLSelectorsCache methodsFor: 'testing'!

+ 0 - 2
st/Helios-Workspace.st

@@ -144,7 +144,6 @@ focus
 !
 
 inspectIt
-
 	| newInspector |
        
 	self announcer announce: (HLInspectItRequested on: model).
@@ -178,7 +177,6 @@ print: aString
 !
 
 printIt
-
 	| result |
 
 	result:=  self doIt.