Browse Source

Full compiler errors handling

Nicolas Petton 11 years ago
parent
commit
232f4d3e30

+ 162 - 0
js/Helios-Announcements.deploy.js

@@ -60,6 +60,114 @@ smalltalk.addClass('HLPrintItRequested', smalltalk.HLCodeHandled, [], 'Helios-An
 smalltalk.addClass('HLDiveRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLErrorRaised', smalltalk.HLAnnouncement, ['error'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_error",
+smalltalk.method({
+selector: "error",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@error"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"error",{}, smalltalk.HLErrorRaised)})},
+messageSends: []}),
+smalltalk.HLErrorRaised);
+
+smalltalk.addMethod(
+"_error_",
+smalltalk.method({
+selector: "error:",
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@error"]=anError;
+return self}, function($ctx1) {$ctx1.fill(self,"error:",{anError:anError}, smalltalk.HLErrorRaised)})},
+messageSends: []}),
+smalltalk.HLErrorRaised);
+
+
+
+smalltalk.addClass('HLCompileErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+
+
+smalltalk.addClass('HLParseErrorRaised', smalltalk.HLErrorRaised, ['line', 'column', 'message'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_column",
+smalltalk.method({
+selector: "column",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@column"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"column",{}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_column_",
+smalltalk.method({
+selector: "column:",
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@column"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"column:",{anInteger:anInteger}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_line",
+smalltalk.method({
+selector: "line",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@line"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"line",{}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_line_",
+smalltalk.method({
+selector: "line:",
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@line"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"line:",{anInteger:anInteger}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_message",
+smalltalk.method({
+selector: "message",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@message"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"message",{}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_message_",
+smalltalk.method({
+selector: "message:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@message"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"message:",{aString:aString}, smalltalk.HLParseErrorRaised)})},
+messageSends: []}),
+smalltalk.HLParseErrorRaised);
+
+
+
+smalltalk.addClass('HLUnknownVariableErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+
+
 smalltalk.addClass('HLFocusRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
@@ -78,6 +186,57 @@ smalltalk.addClass('HLProtocolsFocusRequested', smalltalk.HLFocusRequested, [],
 smalltalk.addClass('HLSourceCodeFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLInstVarAdded', smalltalk.HLAnnouncement, ['theClass', 'variableName'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_theClass",
+smalltalk.method({
+selector: "theClass",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"theClass",{}, smalltalk.HLInstVarAdded)})},
+messageSends: []}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_theClass_",
+smalltalk.method({
+selector: "theClass:",
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@theClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass}, smalltalk.HLInstVarAdded)})},
+messageSends: []}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.HLInstVarAdded)})},
+messageSends: []}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.HLInstVarAdded)})},
+messageSends: []}),
+smalltalk.HLInstVarAdded);
+
+
+
 smalltalk.addClass('HLItemSelected', smalltalk.HLAnnouncement, ['item'], 'Helios-Announcements');
 smalltalk.addMethod(
 "_item",
@@ -139,6 +298,9 @@ smalltalk.addClass('HLProtocolSelected', smalltalk.HLItemSelected, [], 'Helios-A
 smalltalk.addClass('HLRefreshRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLSaveSourceCode', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+
+
 smalltalk.addClass('HLShowCommentToggled', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 

+ 222 - 0
js/Helios-Announcements.js

@@ -75,6 +75,154 @@ smalltalk.addClass('HLPrintItRequested', smalltalk.HLCodeHandled, [], 'Helios-An
 smalltalk.addClass('HLDiveRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLErrorRaised', smalltalk.HLAnnouncement, ['error'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_error",
+smalltalk.method({
+selector: "error",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@error"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"error",{}, smalltalk.HLErrorRaised)})},
+args: [],
+source: "error\x0a\x09^ error",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLErrorRaised);
+
+smalltalk.addMethod(
+"_error_",
+smalltalk.method({
+selector: "error:",
+category: 'accessing',
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@error"]=anError;
+return self}, function($ctx1) {$ctx1.fill(self,"error:",{anError:anError}, smalltalk.HLErrorRaised)})},
+args: ["anError"],
+source: "error: anError\x0a\x09error := anError",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLErrorRaised);
+
+
+
+smalltalk.addClass('HLCompileErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+
+
+smalltalk.addClass('HLParseErrorRaised', smalltalk.HLErrorRaised, ['line', 'column', 'message'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_column",
+smalltalk.method({
+selector: "column",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@column"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"column",{}, smalltalk.HLParseErrorRaised)})},
+args: [],
+source: "column\x0a\x09^ column",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_column_",
+smalltalk.method({
+selector: "column:",
+category: 'accessing',
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@column"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"column:",{anInteger:anInteger}, smalltalk.HLParseErrorRaised)})},
+args: ["anInteger"],
+source: "column: anInteger\x0a\x09column := anInteger",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_line",
+smalltalk.method({
+selector: "line",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@line"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"line",{}, smalltalk.HLParseErrorRaised)})},
+args: [],
+source: "line\x0a\x09^ line",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_line_",
+smalltalk.method({
+selector: "line:",
+category: 'accessing',
+fn: function (anInteger){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@line"]=anInteger;
+return self}, function($ctx1) {$ctx1.fill(self,"line:",{anInteger:anInteger}, smalltalk.HLParseErrorRaised)})},
+args: ["anInteger"],
+source: "line: anInteger\x0a\x09line := anInteger",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_message",
+smalltalk.method({
+selector: "message",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@message"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"message",{}, smalltalk.HLParseErrorRaised)})},
+args: [],
+source: "message\x0a\x09^ message",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+smalltalk.addMethod(
+"_message_",
+smalltalk.method({
+selector: "message:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@message"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"message:",{aString:aString}, smalltalk.HLParseErrorRaised)})},
+args: ["aString"],
+source: "message: aString\x0a\x09message := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLParseErrorRaised);
+
+
+
+smalltalk.addClass('HLUnknownVariableErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+
+
 smalltalk.addClass('HLFocusRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
@@ -93,6 +241,77 @@ smalltalk.addClass('HLProtocolsFocusRequested', smalltalk.HLFocusRequested, [],
 smalltalk.addClass('HLSourceCodeFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLInstVarAdded', smalltalk.HLAnnouncement, ['theClass', 'variableName'], 'Helios-Announcements');
+smalltalk.addMethod(
+"_theClass",
+smalltalk.method({
+selector: "theClass",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@theClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"theClass",{}, smalltalk.HLInstVarAdded)})},
+args: [],
+source: "theClass\x0a\x09^ theClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_theClass_",
+smalltalk.method({
+selector: "theClass:",
+category: 'accessing',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@theClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass}, smalltalk.HLInstVarAdded)})},
+args: ["aClass"],
+source: "theClass: aClass\x0a\x09theClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_variableName",
+smalltalk.method({
+selector: "variableName",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@variableName"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"variableName",{}, smalltalk.HLInstVarAdded)})},
+args: [],
+source: "variableName\x0a\x09^ variableName",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLInstVarAdded);
+
+smalltalk.addMethod(
+"_variableName_",
+smalltalk.method({
+selector: "variableName:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@variableName"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString}, smalltalk.HLInstVarAdded)})},
+args: ["aString"],
+source: "variableName: aString\x0a\x09variableName := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLInstVarAdded);
+
+
+
 smalltalk.addClass('HLItemSelected', smalltalk.HLAnnouncement, ['item'], 'Helios-Announcements');
 smalltalk.addMethod(
 "_item",
@@ -169,6 +388,9 @@ smalltalk.addClass('HLProtocolSelected', smalltalk.HLItemSelected, [], 'Helios-A
 smalltalk.addClass('HLRefreshRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 
+smalltalk.addClass('HLSaveSourceCode', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+
+
 smalltalk.addClass('HLShowCommentToggled', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
 
 

+ 232 - 10
js/Helios-Browser.deploy.js

@@ -1522,6 +1522,23 @@ smalltalk.HLProtocolsListWidget);
 
 
 smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedSelector', 'showInstance', 'showComment'], 'Helios-Browser');
+smalltalk.addMethod(
+"_addInstVarNamed_",
+smalltalk.method({
+selector: "addInstVarNamed:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(self)._environment())._addInstVarNamed_to_(aString,_st(self)._selectedClass());
+$1=_st((smalltalk.HLInstVarAdded || HLInstVarAdded))._new();
+_st($1)._theClass_(_st(self)._selectedClass());
+_st($1)._variableName_(aString);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"addInstVarNamed:",{aString:aString}, smalltalk.HLBrowserModel)})},
+messageSends: ["addInstVarNamed:to:", "selectedClass", "environment", "announce:", "theClass:", "new", "variableName:", "yourself", "announcer"]}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_allProtocol",
 smalltalk.method({
@@ -1552,6 +1569,61 @@ return $1;
 messageSends: ["ifNil:", "new"]}),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_compilationProtocol",
+smalltalk.method({
+selector: "compilationProtocol",
+fn: function (){
+var self=this;
+var currentProtocol;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+currentProtocol=_st(self)._selectedProtocol();
+$2=_st(currentProtocol).__eq(_st(self)._allProtocol());
+if(smalltalk.assert($2)){
+$1=_st(self)._unclassifiedProtocol();
+} else {
+$1=currentProtocol;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compilationProtocol",{currentProtocol:currentProtocol}, smalltalk.HLBrowserModel)})},
+messageSends: ["selectedProtocol", "ifTrue:ifFalse:", "unclassifiedProtocol", "=", "allProtocol"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileClassComment_",
+smalltalk.method({
+selector: "compileClassComment:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._compileClassComment_for_(aString,_st(self)._selectedClass());
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassComment:",{aString:aString}, smalltalk.HLBrowserModel)})},
+messageSends: ["compileClassComment:for:", "selectedClass", "environment"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileClassDefinition_",
+smalltalk.method({
+selector: "compileClassDefinition:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._compileClassDefinition_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassDefinition:",{aString:aString}, smalltalk.HLBrowserModel)})},
+messageSends: ["compileClassDefinition:", "environment"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileMethod_",
+smalltalk.method({
+selector: "compileMethod:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._withCompileErrorHandling_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._environment())._compileMethod_for_protocol_(aString,_st(self)._selectedClass(),_st(self)._compilationProtocol());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"compileMethod:",{aString:aString}, smalltalk.HLBrowserModel)})},
+messageSends: ["withCompileErrorHandling:", "compileMethod:for:protocol:", "selectedClass", "compilationProtocol", "environment"]}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_environment",
 smalltalk.method({
@@ -1636,6 +1708,61 @@ return self}, function($ctx1) {$ctx1.fill(self,"focusOnSourceCode",{}, smalltalk
 messageSends: ["announce:", "new", "announcer"]}),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_handleCompileError_",
+smalltalk.method({
+selector: "handleCompileError:",
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.HLCompileErrorRaised || HLCompileErrorRaised))._new();
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleCompileError:",{anError:anError}, smalltalk.HLBrowserModel)})},
+messageSends: ["announce:", "error:", "new", "yourself", "announcer"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_handleParseError_",
+smalltalk.method({
+selector: "handleParseError:",
+fn: function (anError){
+var self=this;
+var split,line,column,messageToInsert;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+split=_st(_st(anError)._messageText())._tokenize_(" : ");
+messageToInsert=_st(split)._second();
+split=_st(_st(split)._first())._copyFrom_to_((21),_st(_st(split)._first())._size());
+split=_st(split)._tokenize_(" column ");
+line=_st(split)._first();
+column=_st(split)._second();
+$1=_st((smalltalk.HLParseErrorRaised || HLParseErrorRaised))._new();
+_st($1)._line_(_st(line)._asNumber());
+_st($1)._column_(_st(column)._asNumber());
+_st($1)._message_(messageToInsert);
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleParseError:",{anError:anError,split:split,line:line,column:column,messageToInsert:messageToInsert}, smalltalk.HLBrowserModel)})},
+messageSends: ["tokenize:", "messageText", "second", "copyFrom:to:", "size", "first", "announce:", "line:", "asNumber", "new", "column:", "message:", "error:", "yourself", "announcer"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_handleUnkownVariableError_",
+smalltalk.method({
+selector: "handleUnkownVariableError:",
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.HLUnknownVariableErrorRaised || HLUnknownVariableErrorRaised))._new();
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleUnkownVariableError:",{anError:anError}, smalltalk.HLBrowserModel)})},
+messageSends: ["announce:", "error:", "new", "yourself", "announcer"]}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -1649,6 +1776,39 @@ return $1;
 messageSends: ["packages", "environment"]}),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_save_",
+smalltalk.method({
+selector: "save:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(self)._shouldCompileClassDefinition();
+if(smalltalk.assert($1)){
+_st(self)._compileClassDefinition_(aString);
+} else {
+$2=_st(self)._shouldCompileClassComment();
+if(smalltalk.assert($2)){
+_st(self)._compileClassComment_(aString);
+} else {
+_st(self)._compileMethod_(aString);
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"save:",{aString:aString}, smalltalk.HLBrowserModel)})},
+messageSends: ["ifTrue:ifFalse:", "compileClassDefinition:", "compileClassComment:", "compileMethod:", "shouldCompileClassComment", "shouldCompileClassDefinition"]}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_saveSourceCode",
+smalltalk.method({
+selector: "saveSourceCode",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._announcer())._announce_(_st((smalltalk.HLSaveSourceCode || HLSaveSourceCode))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"saveSourceCode",{}, smalltalk.HLBrowserModel)})},
+messageSends: ["announce:", "new", "announcer"]}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_selectedClass",
 smalltalk.method({
@@ -1668,19 +1828,25 @@ smalltalk.method({
 selector: "selectedClass:",
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
 $1=_st(self["@selectedClass"]).__eq(aClass);
 if(smalltalk.assert($1)){
-$2=self;
-return $2;
+$2=aClass;
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=self;
+return $3;
+} else {
+$2;
 };
-$3=aClass;
-if(($receiver = $3) == nil || $receiver == undefined){
+_st(self)._selectedProtocol_(nil);
+};
+$4=aClass;
+if(($receiver = $4) == nil || $receiver == undefined){
 self["@selectedClass"]=nil;
 self["@selectedClass"];
 } else {
-$4=_st(self)._showInstance();
-if(smalltalk.assert($4)){
+$5=_st(self)._showInstance();
+if(smalltalk.assert($5)){
 self["@selectedClass"]=_st(aClass)._theNonMetaClass();
 self["@selectedClass"];
 } else {
@@ -1691,7 +1857,7 @@ self["@selectedClass"];
 _st(self)._selectedProtocol_(nil);
 _st(_st(self)._announcer())._announce_(_st((smalltalk.HLClassSelected || HLClassSelected))._on_(_st(self)._selectedClass()));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedClass:",{aClass:aClass}, smalltalk.HLBrowserModel)})},
-messageSends: ["ifTrue:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "selectedProtocol:", "announce:", "on:", "selectedClass", "announcer"]}),
+messageSends: ["ifTrue:", "ifNil:", "selectedProtocol:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "selectedClass", "announcer"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -1806,6 +1972,30 @@ return self}, function($ctx1) {$ctx1.fill(self,"selectedProtocol:",{aString:aStr
 messageSends: ["ifTrue:", "=", "selectedMethod:", "announce:", "on:", "announcer"]}),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_shouldCompileClassComment",
+smalltalk.method({
+selector: "shouldCompileClassComment",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"shouldCompileClassComment",{}, smalltalk.HLBrowserModel)})},
+messageSends: []}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_shouldCompileClassDefinition",
+smalltalk.method({
+selector: "shouldCompileClassDefinition",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._selectedProtocol())._isNil();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"shouldCompileClassDefinition",{}, smalltalk.HLBrowserModel)})},
+messageSends: ["isNil", "selectedProtocol"]}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_showComment",
 smalltalk.method({
@@ -1880,6 +2070,38 @@ return self}, function($ctx1) {$ctx1.fill(self,"showInstance:",{aBoolean:aBoolea
 messageSends: ["ifNotNil:", "selectedClass:", "ifTrue:ifFalse:", "theNonMetaClass", "selectedClass", "theMetaClass", "announce:", "new", "announcer"]}),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_unclassifiedProtocol",
+smalltalk.method({
+selector: "unclassifiedProtocol",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return "as yet unclassified";
+}, function($ctx1) {$ctx1.fill(self,"unclassifiedProtocol",{}, smalltalk.HLBrowserModel)})},
+messageSends: []}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_withCompileErrorHandling_",
+smalltalk.method({
+selector: "withCompileErrorHandling:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(aBlock)._on_do_((smalltalk.ParseError || ParseError),(function(ex){
+return smalltalk.withContext(function($ctx4) {
return _st(self)._handleParseError_(ex);
+}, function($ctx4) {$ctx4.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}))._on_do_((smalltalk.UnknownVariableError || UnknownVariableError),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._handleUnkownVariableError_(ex);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.CompilerError || CompilerError),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._handleCompileError_(ex);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withCompileErrorHandling:",{aBlock:aBlock}, smalltalk.HLBrowserModel)})},
+messageSends: ["on:do:", "handleCompileError:", "handleUnkownVariableError:", "handleParseError:"]}),
+smalltalk.HLBrowserModel);
+
 
 smalltalk.addMethod(
 "_on_",
@@ -1908,14 +2130,14 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$1;
 $2=self["@codeWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@codeWidget"]=_st((smalltalk.HLCodeWidget || HLCodeWidget))._new();
+self["@codeWidget"]=_st((smalltalk.HLSourceCodeWidget || HLSourceCodeWidget))._on_(_st(self)._model());
 $1=self["@codeWidget"];
 } else {
 $1=$2;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"codeWidget",{}, smalltalk.HLBrowserSourceWidget)})},
-messageSends: ["ifNil:", "new"]}),
+messageSends: ["ifNil:", "on:", "model"]}),
 smalltalk.HLBrowserSourceWidget);
 
 smalltalk.addMethod(

+ 306 - 14
js/Helios-Browser.js

@@ -1977,11 +1977,33 @@ smalltalk.HLProtocolsListWidget);
 
 
 smalltalk.addClass('HLBrowserModel', smalltalk.Object, ['announcer', 'environment', 'selectedPackage', 'selectedClass', 'selectedProtocol', 'selectedSelector', 'showInstance', 'showComment'], 'Helios-Browser');
+smalltalk.addMethod(
+"_addInstVarNamed_",
+smalltalk.method({
+selector: "addInstVarNamed:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+_st(_st(self)._environment())._addInstVarNamed_to_(aString,_st(self)._selectedClass());
+$1=_st((smalltalk.HLInstVarAdded || HLInstVarAdded))._new();
+_st($1)._theClass_(_st(self)._selectedClass());
+_st($1)._variableName_(aString);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"addInstVarNamed:",{aString:aString}, smalltalk.HLBrowserModel)})},
+args: ["aString"],
+source: "addInstVarNamed: aString\x0a\x09self environment addInstVarNamed: aString to: self selectedClass.\x0a\x09self announcer announce: (HLInstVarAdded new\x0a\x09\x09theClass: self selectedClass;\x0a\x09\x09variableName: aString;\x0a\x09\x09yourself)",
+messageSends: ["addInstVarNamed:to:", "selectedClass", "environment", "announce:", "theClass:", "new", "variableName:", "yourself", "announcer"],
+referencedClasses: ["HLInstVarAdded"]
+}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_allProtocol",
 smalltalk.method({
 selector: "allProtocol",
-category: 'accessing',
+category: 'defaults',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return "-- All --";
@@ -2017,6 +2039,81 @@ referencedClasses: ["Announcer"]
 }),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_compilationProtocol",
+smalltalk.method({
+selector: "compilationProtocol",
+category: 'private',
+fn: function (){
+var self=this;
+var currentProtocol;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+currentProtocol=_st(self)._selectedProtocol();
+$2=_st(currentProtocol).__eq(_st(self)._allProtocol());
+if(smalltalk.assert($2)){
+$1=_st(self)._unclassifiedProtocol();
+} else {
+$1=currentProtocol;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compilationProtocol",{currentProtocol:currentProtocol}, smalltalk.HLBrowserModel)})},
+args: [],
+source: "compilationProtocol\x0a\x09| currentProtocol |\x0a\x09\x0a\x09currentProtocol := self selectedProtocol.\x0a\x0a\x09^ currentProtocol = self allProtocol\x0a\x09\x09ifTrue: [ self unclassifiedProtocol ]\x0a\x09\x09ifFalse: [ currentProtocol ]",
+messageSends: ["selectedProtocol", "ifTrue:ifFalse:", "unclassifiedProtocol", "=", "allProtocol"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileClassComment_",
+smalltalk.method({
+selector: "compileClassComment:",
+category: 'compiling',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._compileClassComment_for_(aString,_st(self)._selectedClass());
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassComment:",{aString:aString}, smalltalk.HLBrowserModel)})},
+args: ["aString"],
+source: "compileClassComment: aString\x0a\x09self environment \x0a\x09\x09compileClassComment: aString \x0a\x09\x09for: self selectedClass",
+messageSends: ["compileClassComment:for:", "selectedClass", "environment"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileClassDefinition_",
+smalltalk.method({
+selector: "compileClassDefinition:",
+category: 'compiling',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._environment())._compileClassDefinition_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassDefinition:",{aString:aString}, smalltalk.HLBrowserModel)})},
+args: ["aString"],
+source: "compileClassDefinition: aString\x0a\x09self environment compileClassDefinition: aString",
+messageSends: ["compileClassDefinition:", "environment"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_compileMethod_",
+smalltalk.method({
+selector: "compileMethod:",
+category: 'compiling',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._withCompileErrorHandling_((function(){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._environment())._compileMethod_for_protocol_(aString,_st(self)._selectedClass(),_st(self)._compilationProtocol());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"compileMethod:",{aString:aString}, smalltalk.HLBrowserModel)})},
+args: ["aString"],
+source: "compileMethod: aString\x0a\x09self withCompileErrorHandling: [ self environment \x0a\x09\x09compileMethod: aString \x0a\x09\x09for: self selectedClass\x0a\x09\x09protocol: self compilationProtocol ]",
+messageSends: ["withCompileErrorHandling:", "compileMethod:for:protocol:", "selectedClass", "compilationProtocol", "environment"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_environment",
 smalltalk.method({
@@ -2136,6 +2233,76 @@ referencedClasses: ["HLSourceCodeFocusRequested"]
 }),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_handleCompileError_",
+smalltalk.method({
+selector: "handleCompileError:",
+category: 'error handling',
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.HLCompileErrorRaised || HLCompileErrorRaised))._new();
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleCompileError:",{anError:anError}, smalltalk.HLBrowserModel)})},
+args: ["anError"],
+source: "handleCompileError: anError\x0a\x09self announcer announce: (HLCompileErrorRaised new\x0a\x09\x09error: anError;\x0a\x09\x09yourself)",
+messageSends: ["announce:", "error:", "new", "yourself", "announcer"],
+referencedClasses: ["HLCompileErrorRaised"]
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_handleParseError_",
+smalltalk.method({
+selector: "handleParseError:",
+category: 'error handling',
+fn: function (anError){
+var self=this;
+var split,line,column,messageToInsert;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+split=_st(_st(anError)._messageText())._tokenize_(" : ");
+messageToInsert=_st(split)._second();
+split=_st(_st(split)._first())._copyFrom_to_((21),_st(_st(split)._first())._size());
+split=_st(split)._tokenize_(" column ");
+line=_st(split)._first();
+column=_st(split)._second();
+$1=_st((smalltalk.HLParseErrorRaised || HLParseErrorRaised))._new();
+_st($1)._line_(_st(line)._asNumber());
+_st($1)._column_(_st(column)._asNumber());
+_st($1)._message_(messageToInsert);
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleParseError:",{anError:anError,split:split,line:line,column:column,messageToInsert:messageToInsert}, smalltalk.HLBrowserModel)})},
+args: ["anError"],
+source: "handleParseError: anError\x0a\x09| split line column messageToInsert |\x0a\x09\x0a\x09split := anError messageText tokenize: ' : '.\x0a\x09messageToInsert := split second.\x0a\x0a\x09\x2221 = 'Parse error on line ' size + 1\x22\x0a\x09split := split first copyFrom: 21 to: split first size.\x0a\x09\x0a\x09split := split tokenize: ' column '.\x0a\x09line := split first.\x0a\x09column := split second.\x0a\x09\x0a\x09self announcer announce: (HLParseErrorRaised new\x0a\x09\x09line: line asNumber;\x0a\x09\x09column: column asNumber;\x0a\x09\x09message: messageToInsert;\x0a\x09\x09error: anError;\x0a\x09\x09yourself)",
+messageSends: ["tokenize:", "messageText", "second", "copyFrom:to:", "size", "first", "announce:", "line:", "asNumber", "new", "column:", "message:", "error:", "yourself", "announcer"],
+referencedClasses: ["HLParseErrorRaised"]
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_handleUnkownVariableError_",
+smalltalk.method({
+selector: "handleUnkownVariableError:",
+category: 'error handling',
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st((smalltalk.HLUnknownVariableErrorRaised || HLUnknownVariableErrorRaised))._new();
+_st($1)._error_(anError);
+$2=_st($1)._yourself();
+_st(_st(self)._announcer())._announce_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"handleUnkownVariableError:",{anError:anError}, smalltalk.HLBrowserModel)})},
+args: ["anError"],
+source: "handleUnkownVariableError: anError\x0a\x09self announcer announce: (HLUnknownVariableErrorRaised new\x0a\x09\x09error: anError;\x0a\x09\x09yourself)",
+messageSends: ["announce:", "error:", "new", "yourself", "announcer"],
+referencedClasses: ["HLUnknownVariableErrorRaised"]
+}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_packages",
 smalltalk.method({
@@ -2154,6 +2321,49 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_save_",
+smalltalk.method({
+selector: "save:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(self)._shouldCompileClassDefinition();
+if(smalltalk.assert($1)){
+_st(self)._compileClassDefinition_(aString);
+} else {
+$2=_st(self)._shouldCompileClassComment();
+if(smalltalk.assert($2)){
+_st(self)._compileClassComment_(aString);
+} else {
+_st(self)._compileMethod_(aString);
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"save:",{aString:aString}, smalltalk.HLBrowserModel)})},
+args: ["aString"],
+source: "save: aString\x0a\x09self shouldCompileClassDefinition \x0a\x09\x09ifTrue: [ self compileClassDefinition: aString ]\x0a\x09\x09ifFalse: [ \x0a\x09\x09\x09self shouldCompileClassComment \x0a\x09\x09\x09\x09ifTrue: [ self compileClassComment: aString ]\x0a\x09\x09\x09\x09ifFalse: [ self compileMethod: aString ] ]",
+messageSends: ["ifTrue:ifFalse:", "compileClassDefinition:", "compileClassComment:", "compileMethod:", "shouldCompileClassComment", "shouldCompileClassDefinition"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_saveSourceCode",
+smalltalk.method({
+selector: "saveSourceCode",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._announcer())._announce_(_st((smalltalk.HLSaveSourceCode || HLSaveSourceCode))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"saveSourceCode",{}, smalltalk.HLBrowserModel)})},
+args: [],
+source: "saveSourceCode\x0a\x09self announcer announce: HLSaveSourceCode new",
+messageSends: ["announce:", "new", "announcer"],
+referencedClasses: ["HLSaveSourceCode"]
+}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_selectedClass",
 smalltalk.method({
@@ -2179,19 +2389,25 @@ selector: "selectedClass:",
 category: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5;
 $1=_st(self["@selectedClass"]).__eq(aClass);
 if(smalltalk.assert($1)){
-$2=self;
-return $2;
+$2=aClass;
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=self;
+return $3;
+} else {
+$2;
 };
-$3=aClass;
-if(($receiver = $3) == nil || $receiver == undefined){
+_st(self)._selectedProtocol_(nil);
+};
+$4=aClass;
+if(($receiver = $4) == nil || $receiver == undefined){
 self["@selectedClass"]=nil;
 self["@selectedClass"];
 } else {
-$4=_st(self)._showInstance();
-if(smalltalk.assert($4)){
+$5=_st(self)._showInstance();
+if(smalltalk.assert($5)){
 self["@selectedClass"]=_st(aClass)._theNonMetaClass();
 self["@selectedClass"];
 } else {
@@ -2203,8 +2419,8 @@ _st(self)._selectedProtocol_(nil);
 _st(_st(self)._announcer())._announce_(_st((smalltalk.HLClassSelected || HLClassSelected))._on_(_st(self)._selectedClass()));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedClass:",{aClass:aClass}, smalltalk.HLBrowserModel)})},
 args: ["aClass"],
-source: "selectedClass: aClass\x0a\x09selectedClass = aClass ifTrue: [ ^ self ].\x0a    \x0a\x09aClass \x0a   \x09\x09ifNil: [ selectedClass := nil ]\x0a    \x09ifNotNil: [\x0a\x09\x09\x09self showInstance \x0a   \x09\x09\x09\x09ifTrue: [ selectedClass := aClass theNonMetaClass ]\x0a     \x09\x09\x09ifFalse: [ selectedClass := aClass theMetaClass ] ].\x0a\x09self selectedProtocol: nil.\x0a\x09self announcer announce: (HLClassSelected on: self selectedClass)",
-messageSends: ["ifTrue:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "selectedProtocol:", "announce:", "on:", "selectedClass", "announcer"],
+source: "selectedClass: aClass\x0a\x09selectedClass = aClass ifTrue: [ \x0a\x09\x09aClass ifNil: [ ^ self ].\x0a\x09\x09self selectedProtocol: nil ].\x0a    \x0a\x09aClass \x0a   \x09\x09ifNil: [ selectedClass := nil ]\x0a    \x09ifNotNil: [\x0a\x09\x09\x09self showInstance \x0a   \x09\x09\x09\x09ifTrue: [ selectedClass := aClass theNonMetaClass ]\x0a     \x09\x09\x09ifFalse: [ selectedClass := aClass theMetaClass ] ].\x0a\x09self selectedProtocol: nil.\x0a\x09self announcer announce: (HLClassSelected on: self selectedClass)",
+messageSends: ["ifTrue:", "ifNil:", "selectedProtocol:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "selectedClass", "announcer"],
 referencedClasses: ["HLClassSelected"]
 }),
 smalltalk.HLBrowserModel);
@@ -2351,6 +2567,40 @@ referencedClasses: ["HLProtocolSelected"]
 }),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_shouldCompileClassComment",
+smalltalk.method({
+selector: "shouldCompileClassComment",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"shouldCompileClassComment",{}, smalltalk.HLBrowserModel)})},
+args: [],
+source: "shouldCompileClassComment\x0a\x09\x22TODO\x22\x0a\x09\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_shouldCompileClassDefinition",
+smalltalk.method({
+selector: "shouldCompileClassDefinition",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._selectedProtocol())._isNil();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"shouldCompileClassDefinition",{}, smalltalk.HLBrowserModel)})},
+args: [],
+source: "shouldCompileClassDefinition\x0a\x09^ self selectedProtocol isNil",
+messageSends: ["isNil", "selectedProtocol"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
 smalltalk.addMethod(
 "_showComment",
 smalltalk.method({
@@ -2445,6 +2695,48 @@ referencedClasses: ["HLShowInstanceToggled"]
 }),
 smalltalk.HLBrowserModel);
 
+smalltalk.addMethod(
+"_unclassifiedProtocol",
+smalltalk.method({
+selector: "unclassifiedProtocol",
+category: 'defaults',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return "as yet unclassified";
+}, function($ctx1) {$ctx1.fill(self,"unclassifiedProtocol",{}, smalltalk.HLBrowserModel)})},
+args: [],
+source: "unclassifiedProtocol\x0a\x09^ 'as yet unclassified'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserModel);
+
+smalltalk.addMethod(
+"_withCompileErrorHandling_",
+smalltalk.method({
+selector: "withCompileErrorHandling:",
+category: 'error handling',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st((function(){
+return smalltalk.withContext(function($ctx2) {
return _st((function(){
+return smalltalk.withContext(function($ctx3) {
return _st(aBlock)._on_do_((smalltalk.ParseError || ParseError),(function(ex){
+return smalltalk.withContext(function($ctx4) {
return _st(self)._handleParseError_(ex);
+}, function($ctx4) {$ctx4.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}))._on_do_((smalltalk.UnknownVariableError || UnknownVariableError),(function(ex){
+return smalltalk.withContext(function($ctx3) {
return _st(self)._handleUnkownVariableError_(ex);
+}, function($ctx3) {$ctx3.fillBlock({ex:ex},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_((smalltalk.CompilerError || CompilerError),(function(ex){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._handleCompileError_(ex);
+}, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"withCompileErrorHandling:",{aBlock:aBlock}, smalltalk.HLBrowserModel)})},
+args: ["aBlock"],
+source: "withCompileErrorHandling: aBlock\x0a\x09[\x0a\x09\x09[\x0a\x09\x09\x09aBlock \x0a\x09\x09\x09\x09on: ParseError\x0a\x09\x09\x09\x09do: [:ex | self handleParseError: ex ]\x0a\x09\x09]\x0a\x09\x09\x09on: UnknownVariableError\x0a\x09\x09\x09do: [ :ex | self handleUnkownVariableError: ex ]\x0a\x09]\x0a\x09\x09on: CompilerError\x0a\x09\x09do: [ :ex | self handleCompileError: ex ]",
+messageSends: ["on:do:", "handleCompileError:", "handleUnkownVariableError:", "handleParseError:"],
+referencedClasses: ["CompilerError", "UnknownVariableError", "ParseError"]
+}),
+smalltalk.HLBrowserModel);
+
 
 smalltalk.addMethod(
 "_on_",
@@ -2479,7 +2771,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$1;
 $2=self["@codeWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@codeWidget"]=_st((smalltalk.HLCodeWidget || HLCodeWidget))._new();
+self["@codeWidget"]=_st((smalltalk.HLSourceCodeWidget || HLSourceCodeWidget))._on_(_st(self)._model());
 $1=self["@codeWidget"];
 } else {
 $1=$2;
@@ -2487,9 +2779,9 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"codeWidget",{}, smalltalk.HLBrowserSourceWidget)})},
 args: [],
-source: "codeWidget\x0a\x09^ codeWidget ifNil: [ codeWidget := HLCodeWidget new ]",
-messageSends: ["ifNil:", "new"],
-referencedClasses: ["HLCodeWidget"]
+source: "codeWidget\x0a\x09^ codeWidget ifNil: [ codeWidget := HLSourceCodeWidget on: self model ]",
+messageSends: ["ifNil:", "on:", "model"],
+referencedClasses: ["HLSourceCodeWidget"]
 }),
 smalltalk.HLBrowserSourceWidget);
 

+ 24 - 0
js/Helios-Core.deploy.js

@@ -121,6 +121,30 @@ smalltalk.HLTab.klass);
 
 
 smalltalk.addClass('HLWidget', smalltalk.Widget, ['wrapper'], 'Helios-Core');
+smalltalk.addMethod(
+"_alert_",
+smalltalk.method({
+selector: "alert:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(window)._alert_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString}, smalltalk.HLWidget)})},
+messageSends: ["alert:"]}),
+smalltalk.HLWidget);
+
+smalltalk.addMethod(
+"_confirm_",
+smalltalk.method({
+selector: "confirm:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(window)._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString}, smalltalk.HLWidget)})},
+messageSends: ["confirm:"]}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 "_manager",
 smalltalk.method({

+ 34 - 0
js/Helios-Core.js

@@ -166,6 +166,40 @@ smalltalk.HLTab.klass);
 
 
 smalltalk.addClass('HLWidget', smalltalk.Widget, ['wrapper'], 'Helios-Core');
+smalltalk.addMethod(
+"_alert_",
+smalltalk.method({
+selector: "alert:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(window)._alert_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString}, smalltalk.HLWidget)})},
+args: ["aString"],
+source: "alert: aString\x0a\x09window alert: aString",
+messageSends: ["alert:"],
+referencedClasses: []
+}),
+smalltalk.HLWidget);
+
+smalltalk.addMethod(
+"_confirm_",
+smalltalk.method({
+selector: "confirm:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(window)._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString}, smalltalk.HLWidget)})},
+args: ["aString"],
+source: "confirm: aString\x0a\x09^ window confirm: aString",
+messageSends: ["confirm:"],
+referencedClasses: []
+}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 "_manager",
 smalltalk.method({

+ 74 - 0
js/Helios-Environments.deploy.js

@@ -1,5 +1,66 @@
 smalltalk.addPackage('Helios-Environments');
 smalltalk.addClass('HLEnvironment', smalltalk.Object, [], 'Helios-Environments');
+smalltalk.addMethod(
+"_addInstVarNamed_to_",
+smalltalk.method({
+selector: "addInstVarNamed:to:",
+fn: function (aString,aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(aClass)._instanceVariableNames())._copy();
+_st($1)._add_(aString);
+$2=_st($1)._yourself();
+_st(_st(self)._classBuilder())._addSubclassOf_named_instanceVariableNames_package_(_st(aClass)._superclass(),_st(aClass)._name(),$2,_st(_st(aClass)._package())._name());
+return self}, function($ctx1) {$ctx1.fill(self,"addInstVarNamed:to:",{aString:aString,aClass:aClass}, smalltalk.HLEnvironment)})},
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "superclass", "name", "add:", "copy", "instanceVariableNames", "yourself", "package", "classBuilder"]}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_classBuilder",
+smalltalk.method({
+selector: "classBuilder",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._subclassResponsibility();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"classBuilder",{}, smalltalk.HLEnvironment)})},
+messageSends: ["subclassResponsibility"]}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileClassComment_for_",
+smalltalk.method({
+selector: "compileClassComment:for:",
+fn: function (aString,aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(aClass)._comment_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassComment:for:",{aString:aString,aClass:aClass}, smalltalk.HLEnvironment)})},
+messageSends: ["comment:"]}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileClassDefinition_",
+smalltalk.method({
+selector: "compileClassDefinition:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._eval_on_(aString,_st((smalltalk.DoIt || DoIt))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassDefinition:",{aString:aString}, smalltalk.HLEnvironment)})},
+messageSends: ["eval:on:", "new"]}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileMethod_for_protocol_",
+smalltalk.method({
+selector: "compileMethod:for:protocol:",
+fn: function (sourceCode,class_,protocol){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(class_)._compile_category_(sourceCode,protocol);
+return self}, function($ctx1) {$ctx1.fill(self,"compileMethod:for:protocol:",{sourceCode:sourceCode,class_:class_,protocol:protocol}, smalltalk.HLEnvironment)})},
+messageSends: ["compile:category:"]}),
+smalltalk.HLEnvironment);
+
 smalltalk.addMethod(
 "_eval_on_",
 smalltalk.method({
@@ -29,6 +90,19 @@ smalltalk.HLEnvironment);
 
 
 smalltalk.addClass('HLLocalEnvironment', smalltalk.HLEnvironment, [], 'Helios-Environments');
+smalltalk.addMethod(
+"_classBuilder",
+smalltalk.method({
+selector: "classBuilder",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.ClassBuilder || ClassBuilder))._new();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"classBuilder",{}, smalltalk.HLLocalEnvironment)})},
+messageSends: ["new"]}),
+smalltalk.HLLocalEnvironment);
+
 smalltalk.addMethod(
 "_eval_on_",
 smalltalk.method({

+ 106 - 2
js/Helios-Environments.js

@@ -1,6 +1,92 @@
 smalltalk.addPackage('Helios-Environments');
 smalltalk.addClass('HLEnvironment', smalltalk.Object, [], 'Helios-Environments');
 smalltalk.HLEnvironment.comment="Abstract class defining common behavior for local and remote environments"
+smalltalk.addMethod(
+"_addInstVarNamed_to_",
+smalltalk.method({
+selector: "addInstVarNamed:to:",
+category: 'compiling',
+fn: function (aString,aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(aClass)._instanceVariableNames())._copy();
+_st($1)._add_(aString);
+$2=_st($1)._yourself();
+_st(_st(self)._classBuilder())._addSubclassOf_named_instanceVariableNames_package_(_st(aClass)._superclass(),_st(aClass)._name(),$2,_st(_st(aClass)._package())._name());
+return self}, function($ctx1) {$ctx1.fill(self,"addInstVarNamed:to:",{aString:aString,aClass:aClass}, smalltalk.HLEnvironment)})},
+args: ["aString", "aClass"],
+source: "addInstVarNamed: aString to: aClass\x0a\x09self classBuilder\x0a\x09\x09addSubclassOf: aClass superclass \x0a\x09\x09named: aClass name \x0a\x09\x09instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)\x0a\x09\x09package: aClass package name",
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "superclass", "name", "add:", "copy", "instanceVariableNames", "yourself", "package", "classBuilder"],
+referencedClasses: []
+}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_classBuilder",
+smalltalk.method({
+selector: "classBuilder",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(self)._subclassResponsibility();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"classBuilder",{}, smalltalk.HLEnvironment)})},
+args: [],
+source: "classBuilder\x0a\x09^ self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
+referencedClasses: []
+}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileClassComment_for_",
+smalltalk.method({
+selector: "compileClassComment:for:",
+category: 'compiling',
+fn: function (aString,aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(aClass)._comment_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassComment:for:",{aString:aString,aClass:aClass}, smalltalk.HLEnvironment)})},
+args: ["aString", "aClass"],
+source: "compileClassComment: aString for: aClass\x0a\x09aClass comment: aString",
+messageSends: ["comment:"],
+referencedClasses: []
+}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileClassDefinition_",
+smalltalk.method({
+selector: "compileClassDefinition:",
+category: 'compiling',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._eval_on_(aString,_st((smalltalk.DoIt || DoIt))._new());
+return self}, function($ctx1) {$ctx1.fill(self,"compileClassDefinition:",{aString:aString}, smalltalk.HLEnvironment)})},
+args: ["aString"],
+source: "compileClassDefinition: aString\x0a\x09self eval: aString on: DoIt new",
+messageSends: ["eval:on:", "new"],
+referencedClasses: ["DoIt"]
+}),
+smalltalk.HLEnvironment);
+
+smalltalk.addMethod(
+"_compileMethod_for_protocol_",
+smalltalk.method({
+selector: "compileMethod:for:protocol:",
+category: 'compiling',
+fn: function (sourceCode,class_,protocol){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(class_)._compile_category_(sourceCode,protocol);
+return self}, function($ctx1) {$ctx1.fill(self,"compileMethod:for:protocol:",{sourceCode:sourceCode,class_:class_,protocol:protocol}, smalltalk.HLEnvironment)})},
+args: ["sourceCode", "class", "protocol"],
+source: "compileMethod: sourceCode for: class protocol: protocol\x0a\x09class\x0a\x09\x09compile: sourceCode\x0a\x09\x09category: protocol",
+messageSends: ["compile:category:"],
+referencedClasses: []
+}),
+smalltalk.HLEnvironment);
+
 smalltalk.addMethod(
 "_eval_on_",
 smalltalk.method({
@@ -31,7 +117,7 @@ $1=_st(self)._subclassResponsibility();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"packages",{}, smalltalk.HLEnvironment)})},
 args: [],
-source: "packages\x0a\x0a\x09^ self subclassResponsibility",
+source: "packages\x0a\x09^ self subclassResponsibility",
 messageSends: ["subclassResponsibility"],
 referencedClasses: []
 }),
@@ -40,6 +126,24 @@ smalltalk.HLEnvironment);
 
 
 smalltalk.addClass('HLLocalEnvironment', smalltalk.HLEnvironment, [], 'Helios-Environments');
+smalltalk.addMethod(
+"_classBuilder",
+smalltalk.method({
+selector: "classBuilder",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st((smalltalk.ClassBuilder || ClassBuilder))._new();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"classBuilder",{}, smalltalk.HLLocalEnvironment)})},
+args: [],
+source: "classBuilder\x0a\x09^ ClassBuilder new",
+messageSends: ["new"],
+referencedClasses: ["ClassBuilder"]
+}),
+smalltalk.HLLocalEnvironment);
+
 smalltalk.addMethod(
 "_eval_on_",
 smalltalk.method({
@@ -82,7 +186,7 @@ $1=_st(_st((smalltalk.Smalltalk || Smalltalk))._current())._packages();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"packages",{}, smalltalk.HLLocalEnvironment)})},
 args: [],
-source: "packages\x0a\x0a\x09^ Smalltalk current packages",
+source: "packages\x0a\x09^ Smalltalk current packages",
 messageSends: ["packages", "current"],
 referencedClasses: ["Smalltalk"]
 }),

+ 148 - 222
js/Helios-Workspace.deploy.js

@@ -304,14 +304,14 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$1;
 $2=self["@model"];
 if(($receiver = $2) == nil || $receiver == undefined){
-_st(self)._model_(_st((smalltalk.HLCodeModel || HLCodeModel))._new());
+self["@model"]=_st((smalltalk.HLCodeModel || HLCodeModel))._new();
 $1=self["@model"];
 } else {
 $1=$2;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"model",{}, smalltalk.HLCodeWidget)})},
-messageSends: ["ifNil:", "model:", "new"]}),
+messageSends: ["ifNil:", "new"]}),
 smalltalk.HLCodeWidget);
 
 smalltalk.addMethod(
@@ -537,6 +537,17 @@ messageSends: []}),
 smalltalk.HLCodeWidget);
 
 
+smalltalk.addMethod(
+"_canBeOpenAsTab",
+smalltalk.method({
+selector: "canBeOpenAsTab",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return true;
+}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLCodeWidget.klass)})},
+messageSends: []}),
+smalltalk.HLCodeWidget.klass);
+
 smalltalk.addMethod(
 "_initialize",
 smalltalk.method({
@@ -643,294 +654,209 @@ return self}, function($ctx1) {$ctx1.fill(self,"setupKeyMaps",{}, smalltalk.HLCo
 messageSends: []}),
 smalltalk.HLCodeWidget.klass);
 
-
-smalltalk.addClass('HLSourceCodeWidget', smalltalk.HLCodeWidget, [], 'Helios-Workspace');
-smalltalk.addMethod(
-"_onKeyDown_",
-smalltalk.method({
-selector: "onKeyDown:",
-fn: function (anEvent){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
-$1=smalltalk.HLCodeWidget.fn.prototype._onKeyDown_.apply(_st(self), [anEvent]);
-if(! smalltalk.assert($1)){
-return false;
-};
-$2=_st(anEvent)._ctrlKey();
-if(smalltalk.assert($2)){
-$3=_st(_st(anEvent)._keyCode()).__eq((83));
-if(smalltalk.assert($3)){
-_st(self)._onSave();
-_st(anEvent)._preventDefault();
-return false;
-};
-};
-return self}, function($ctx1) {$ctx1.fill(self,"onKeyDown:",{anEvent:anEvent}, smalltalk.HLSourceCodeWidget)})},
-messageSends: ["ifFalse:", "onKeyDown:", "ifTrue:", "onSave", "preventDefault", "=", "keyCode", "ctrlKey"]}),
-smalltalk.HLSourceCodeWidget);
-
-smalltalk.addMethod(
-"_onSave",
-smalltalk.method({
-selector: "onSave",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onSave",{}, smalltalk.HLSourceCodeWidget)})},
-messageSends: []}),
-smalltalk.HLSourceCodeWidget);
-
-
-
-smalltalk.addClass('HLWorkspace', smalltalk.HLWidget, ['model', 'codeWidget'], 'Helios-Workspace');
-smalltalk.addMethod(
-"_codeWidget",
-smalltalk.method({
-selector: "codeWidget",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-$2=self["@codeWidget"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$3=_st((smalltalk.HLCodeWidget || HLCodeWidget))._new();
-_st($3)._model_(_st(_st(self)._model())._code());
-$4=_st($3)._yourself();
-self["@codeWidget"]=$4;
-$1=self["@codeWidget"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"codeWidget",{}, smalltalk.HLWorkspace)})},
-messageSends: ["ifNil:", "model:", "code", "model", "new", "yourself"]}),
-smalltalk.HLWorkspace);
-
-smalltalk.addMethod(
-"_model",
-smalltalk.method({
-selector: "model",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@model"];
-if(($receiver = $2) == nil || $receiver == undefined){
-_st(self)._model_(_st((smalltalk.HLWorkspaceModel || HLWorkspaceModel))._new());
-$1=self["@model"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"model",{}, smalltalk.HLWorkspace)})},
-messageSends: ["ifNil:", "model:", "new"]}),
-smalltalk.HLWorkspace);
-
-smalltalk.addMethod(
-"_model_",
-smalltalk.method({
-selector: "model:",
-fn: function (aModel){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@model"]=aModel;
-_st(_st(self)._codeWidget())._model_(_st(aModel)._code());
-_st(self)._observeCodeWidget();
-return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel}, smalltalk.HLWorkspace)})},
-messageSends: ["model:", "code", "codeWidget", "observeCodeWidget"]}),
-smalltalk.HLWorkspace);
-
 smalltalk.addMethod(
-"_observeCodeWidget",
+"_tabLabel",
 smalltalk.method({
-selector: "observeCodeWidget",
+selector: "tabLabel",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"observeCodeWidget",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
return "Workspace";
+}, function($ctx1) {$ctx1.fill(self,"tabLabel",{}, smalltalk.HLCodeWidget.klass)})},
 messageSends: []}),
-smalltalk.HLWorkspace);
+smalltalk.HLCodeWidget.klass);
 
 smalltalk.addMethod(
-"_onDoIt",
+"_tabPriority",
 smalltalk.method({
-selector: "onDoIt",
+selector: "tabPriority",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onDoIt",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
return (10);
+}, function($ctx1) {$ctx1.fill(self,"tabPriority",{}, smalltalk.HLCodeWidget.klass)})},
 messageSends: []}),
-smalltalk.HLWorkspace);
+smalltalk.HLCodeWidget.klass);
 
-smalltalk.addMethod(
-"_onInspectIt",
-smalltalk.method({
-selector: "onInspectIt",
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onInspectIt",{}, smalltalk.HLWorkspace)})},
-messageSends: []}),
-smalltalk.HLWorkspace);
 
+smalltalk.addClass('HLSourceCodeWidget', smalltalk.HLCodeWidget, ['browserModel'], 'Helios-Workspace');
 smalltalk.addMethod(
-"_onPrintIt",
+"_browserModel",
 smalltalk.method({
-selector: "onPrintIt",
+selector: "browserModel",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onPrintIt",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@browserModel"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"browserModel",{}, smalltalk.HLSourceCodeWidget)})},
 messageSends: []}),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_renderContentOn_",
+"_browserModel_",
 smalltalk.method({
-selector: "renderContentOn:",
-fn: function (html){
+selector: "browserModel:",
+fn: function (aBrowserModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(_st(self)._codeWidget());
-return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html}, smalltalk.HLWorkspace)})},
-messageSends: ["with:", "codeWidget"]}),
-smalltalk.HLWorkspace);
-
+return smalltalk.withContext(function($ctx1) { 
self["@browserModel"]=aBrowserModel;
+_st(self)._observeBrowserModel();
+return self}, function($ctx1) {$ctx1.fill(self,"browserModel:",{aBrowserModel:aBrowserModel}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["observeBrowserModel"]}),
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_canBeOpenAsTab",
+"_observeBrowserModel",
 smalltalk.method({
-selector: "canBeOpenAsTab",
+selector: "observeBrowserModel",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return true;
-}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLWorkspace.klass)})},
-messageSends: []}),
-smalltalk.HLWorkspace.klass);
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(self)._browserModel())._announcer();
+_st($1)._on_do_((smalltalk.HLSaveSourceCode || HLSaveSourceCode),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onSaveIt();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLParseErrorRaised || HLParseErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onParseError_(ann);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLCompileErrorRaised || HLCompileErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onCompileError_(_st(ann)._error());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLUnknownVariableErrorRaised || HLUnknownVariableErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onUnknownVariableError_(_st(ann)._error());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.HLInstVarAdded || HLInstVarAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onInstVarAdded();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeBrowserModel",{}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded"]}),
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_tabLabel",
+"_onCompileError_",
 smalltalk.method({
-selector: "tabLabel",
-fn: function (){
+selector: "onCompileError:",
+fn: function (anError){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "Workspace";
-}, function($ctx1) {$ctx1.fill(self,"tabLabel",{}, smalltalk.HLWorkspace.klass)})},
-messageSends: []}),
-smalltalk.HLWorkspace.klass);
+return smalltalk.withContext(function($ctx1) { 
_st(self)._alert_(_st(anError)._messageText());
+return self}, function($ctx1) {$ctx1.fill(self,"onCompileError:",{anError:anError}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["alert:", "messageText"]}),
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_tabPriority",
+"_onInstVarAdded",
 smalltalk.method({
-selector: "tabPriority",
+selector: "onInstVarAdded",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return (10);
-}, function($ctx1) {$ctx1.fill(self,"tabPriority",{}, smalltalk.HLWorkspace.klass)})},
-messageSends: []}),
-smalltalk.HLWorkspace.klass);
-
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._save_(_st(self)._contents());
+return self}, function($ctx1) {$ctx1.fill(self,"onInstVarAdded",{}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["save:", "contents", "browserModel"]}),
+smalltalk.HLSourceCodeWidget);
 
-smalltalk.addClass('HLWorkspaceModel', smalltalk.Object, ['announcer', 'environment', 'code'], 'Helios-Workspace');
 smalltalk.addMethod(
-"_announcer",
+"_onParseError_",
 smalltalk.method({
-selector: "announcer",
-fn: function (){
+selector: "onParseError:",
+fn: function (anAnnouncement){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@announcer"];
-if(($receiver = $2) == nil || $receiver == undefined){
-self["@announcer"]=_st((smalltalk.Announcer || Announcer))._new();
-$1=self["@announcer"];
+var lineIndex,newContents;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+lineIndex=(1);
+_st(self)._contents_(_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._contents())._linesDo_((function(each){
+return smalltalk.withContext(function($ctx3) {
$1=_st(lineIndex).__eq(_st(anAnnouncement)._line());
+if(smalltalk.assert($1)){
+$2=stream;
+_st($2)._nextPutAll_(_st(each)._copyFrom_to_((1),_st(anAnnouncement)._column()));
+_st($2)._nextPutAll_("<- ");
+_st($2)._nextPutAll_(_st(anAnnouncement)._message());
+_st($2)._nextPutAll_(" ");
+$3=_st($2)._nextPutAll_(_st(each)._copyFrom_to_(_st(_st(anAnnouncement)._column()).__plus((1)),_st(each)._size()));
+$3;
 } else {
-$1=$2;
+_st(stream)._nextPutAll_(each);
 };
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"announcer",{}, smalltalk.HLWorkspaceModel)})},
-messageSends: ["ifNil:", "new"]}),
-smalltalk.HLWorkspaceModel);
+_st(stream)._nextPutAll_(_st((smalltalk.String || String))._cr());
+lineIndex=_st(lineIndex).__plus((1));
+return lineIndex;
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"onParseError:",{anAnnouncement:anAnnouncement,lineIndex:lineIndex,newContents:newContents}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["contents:", "streamContents:", "linesDo:", "ifTrue:ifFalse:", "nextPutAll:", "copyFrom:to:", "column", "message", "+", "size", "=", "line", "cr", "contents"]}),
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_code",
+"_onSaveIt",
 smalltalk.method({
-selector: "code",
+selector: "onSaveIt",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@code"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$1=_st((smalltalk.HLCodeModel || HLCodeModel))._on_(_st(self)._environment());
-} else {
-$1=$2;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._save_(_st(self)._contents());
+return self}, function($ctx1) {$ctx1.fill(self,"onSaveIt",{}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["save:", "contents", "browserModel"]}),
+smalltalk.HLSourceCodeWidget);
+
+smalltalk.addMethod(
+"_onUnknownVariableError_",
+smalltalk.method({
+selector: "onUnknownVariableError:",
+fn: function (anError){
+var self=this;
+var confirm;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+confirm=_st(self)._confirm_(_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
$1=stream;
+_st($1)._nextPutAll_(_st(anError)._messageText());
+_st($1)._nextPutAll_(_st((smalltalk.String || String))._cr());
+$2=_st($1)._nextPutAll_("Would you like to define an instance variable?");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
+$3=confirm;
+if(! smalltalk.assert($3)){
+$4=self;
+return $4;
 };
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"code",{}, smalltalk.HLWorkspaceModel)})},
-messageSends: ["ifNil:", "on:", "environment"]}),
-smalltalk.HLWorkspaceModel);
+_st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
+return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError,confirm:confirm}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["confirm:", "streamContents:", "nextPutAll:", "messageText", "cr", "ifFalse:", "addInstVarNamed:", "variableName", "browserModel"]}),
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_environment",
+"_saveIt",
 smalltalk.method({
-selector: "environment",
+selector: "saveIt",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@environment"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$1=_st(_st((smalltalk.HLManager || HLManager))._current())._environment();
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"environment",{}, smalltalk.HLWorkspaceModel)})},
-messageSends: ["ifNil:", "environment", "current"]}),
-smalltalk.HLWorkspaceModel);
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._saveSourceCode();
+return self}, function($ctx1) {$ctx1.fill(self,"saveIt",{}, smalltalk.HLSourceCodeWidget)})},
+messageSends: ["saveSourceCode", "browserModel"]}),
+smalltalk.HLSourceCodeWidget);
+
 
 smalltalk.addMethod(
-"_environment_",
+"_canBeOpenAsTab",
 smalltalk.method({
-selector: "environment:",
-fn: function (anEnvironment){
+selector: "canBeOpenAsTab",
+fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@environment"]=anEnvironment;
-return self}, function($ctx1) {$ctx1.fill(self,"environment:",{anEnvironment:anEnvironment}, smalltalk.HLWorkspaceModel)})},
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLSourceCodeWidget.klass)})},
 messageSends: []}),
-smalltalk.HLWorkspaceModel);
-
-smalltalk.addMethod(
-"_onKeyDown_",
-smalltalk.method({
-selector: "onKeyDown:",
-fn: function (anEvent){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
if(anEvent.ctrlKey) {
-		if(anEvent.keyCode === 80) { //ctrl+p
-			self._printIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 68) { //ctrl+d
-			self._doIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 73) { //ctrl+i
-			self._inspectIt();
-			anEvent.preventDefault();
-			return false;
-		}
-	};
-return self}, function($ctx1) {$ctx1.fill(self,"onKeyDown:",{anEvent:anEvent}, smalltalk.HLWorkspaceModel)})},
-messageSends: []}),
-smalltalk.HLWorkspaceModel);
-
+smalltalk.HLSourceCodeWidget.klass);
 
 smalltalk.addMethod(
 "_on_",
 smalltalk.method({
 selector: "on:",
-fn: function (anEnvironment){
+fn: function (aBrowserModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(self)._new();
-_st($2)._environment_(anEnvironment);
+_st($2)._browserModel_(aBrowserModel);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{anEnvironment:anEnvironment}, smalltalk.HLWorkspaceModel.klass)})},
-messageSends: ["environment:", "new", "yourself"]}),
-smalltalk.HLWorkspaceModel.klass);
+}, function($ctx1) {$ctx1.fill(self,"on:",{aBrowserModel:aBrowserModel}, smalltalk.HLSourceCodeWidget.klass)})},
+messageSends: ["browserModel:", "new", "yourself"]}),
+smalltalk.HLSourceCodeWidget.klass);
 
 

+ 184 - 283
js/Helios-Workspace.js

@@ -410,7 +410,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$1;
 $2=self["@model"];
 if(($receiver = $2) == nil || $receiver == undefined){
-_st(self)._model_(_st((smalltalk.HLCodeModel || HLCodeModel))._new());
+self["@model"]=_st((smalltalk.HLCodeModel || HLCodeModel))._new();
 $1=self["@model"];
 } else {
 $1=$2;
@@ -418,8 +418,8 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"model",{}, smalltalk.HLCodeWidget)})},
 args: [],
-source: "model\x0a\x09^ model ifNil: [ \x0a    \x09self model: HLCodeModel new.\x0a\x09\x09model ]",
-messageSends: ["ifNil:", "model:", "new"],
+source: "model\x0a\x09^ model ifNil: [ model := HLCodeModel new ]",
+messageSends: ["ifNil:", "new"],
 referencedClasses: ["HLCodeModel"]
 }),
 smalltalk.HLCodeWidget);
@@ -732,6 +732,22 @@ referencedClasses: []
 smalltalk.HLCodeWidget);
 
 
+smalltalk.addMethod(
+"_canBeOpenAsTab",
+smalltalk.method({
+selector: "canBeOpenAsTab",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return true;
+}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLCodeWidget.klass)})},
+args: [],
+source: "canBeOpenAsTab\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLCodeWidget.klass);
+
 smalltalk.addMethod(
 "_initialize",
 smalltalk.method({
@@ -873,389 +889,274 @@ referencedClasses: []
 }),
 smalltalk.HLCodeWidget.klass);
 
-
-smalltalk.addClass('HLSourceCodeWidget', smalltalk.HLCodeWidget, [], 'Helios-Workspace');
-smalltalk.addMethod(
-"_onKeyDown_",
-smalltalk.method({
-selector: "onKeyDown:",
-category: 'reactions',
-fn: function (anEvent){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
-$1=smalltalk.HLCodeWidget.fn.prototype._onKeyDown_.apply(_st(self), [anEvent]);
-if(! smalltalk.assert($1)){
-return false;
-};
-$2=_st(anEvent)._ctrlKey();
-if(smalltalk.assert($2)){
-$3=_st(_st(anEvent)._keyCode()).__eq((83));
-if(smalltalk.assert($3)){
-_st(self)._onSave();
-_st(anEvent)._preventDefault();
-return false;
-};
-};
-return self}, function($ctx1) {$ctx1.fill(self,"onKeyDown:",{anEvent:anEvent}, smalltalk.HLSourceCodeWidget)})},
-args: ["anEvent"],
-source: "onKeyDown: anEvent\x0a\x09(super onKeyDown: anEvent) ifFalse: [ ^ false ].\x0a    \x0a\x09anEvent ctrlKey ifTrue: [\x0a\x09\x09anEvent keyCode = 83 ifTrue: [\x0a\x09\x09\x09self onSave.\x0a\x09\x09\x09anEvent preventDefault.\x0a\x09\x09\x09^ false ] ]",
-messageSends: ["ifFalse:", "onKeyDown:", "ifTrue:", "onSave", "preventDefault", "=", "keyCode", "ctrlKey"],
-referencedClasses: []
-}),
-smalltalk.HLSourceCodeWidget);
-
 smalltalk.addMethod(
-"_onSave",
+"_tabLabel",
 smalltalk.method({
-selector: "onSave",
-category: 'reactions',
+selector: "tabLabel",
+category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onSave",{}, smalltalk.HLSourceCodeWidget)})},
+return smalltalk.withContext(function($ctx1) { 
return "Workspace";
+}, function($ctx1) {$ctx1.fill(self,"tabLabel",{}, smalltalk.HLCodeWidget.klass)})},
 args: [],
-source: "onSave",
+source: "tabLabel\x0a\x09^ 'Workspace'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSourceCodeWidget);
-
-
+smalltalk.HLCodeWidget.klass);
 
-smalltalk.addClass('HLWorkspace', smalltalk.HLWidget, ['model', 'codeWidget'], 'Helios-Workspace');
 smalltalk.addMethod(
-"_codeWidget",
+"_tabPriority",
 smalltalk.method({
-selector: "codeWidget",
+selector: "tabPriority",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$1;
-$2=self["@codeWidget"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$3=_st((smalltalk.HLCodeWidget || HLCodeWidget))._new();
-_st($3)._model_(_st(_st(self)._model())._code());
-$4=_st($3)._yourself();
-self["@codeWidget"]=$4;
-$1=self["@codeWidget"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"codeWidget",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
return (10);
+}, function($ctx1) {$ctx1.fill(self,"tabPriority",{}, smalltalk.HLCodeWidget.klass)})},
 args: [],
-source: "codeWidget\x0a\x09^ codeWidget ifNil: [\x0a\x09\x09codeWidget := HLCodeWidget new\x0a    \x09\x09model: self model code;\x0a        \x09yourself ]",
-messageSends: ["ifNil:", "model:", "code", "model", "new", "yourself"],
-referencedClasses: ["HLCodeWidget"]
+source: "tabPriority\x0a\x09^ 10",
+messageSends: [],
+referencedClasses: []
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLCodeWidget.klass);
+
 
+smalltalk.addClass('HLSourceCodeWidget', smalltalk.HLCodeWidget, ['browserModel'], 'Helios-Workspace');
 smalltalk.addMethod(
-"_model",
+"_browserModel",
 smalltalk.method({
-selector: "model",
+selector: "browserModel",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@model"];
-if(($receiver = $2) == nil || $receiver == undefined){
-_st(self)._model_(_st((smalltalk.HLWorkspaceModel || HLWorkspaceModel))._new());
-$1=self["@model"];
-} else {
-$1=$2;
-};
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@browserModel"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"model",{}, smalltalk.HLWorkspace)})},
+}, function($ctx1) {$ctx1.fill(self,"browserModel",{}, smalltalk.HLSourceCodeWidget)})},
 args: [],
-source: "model\x0a\x09^ model ifNil: [ \x0a    \x09self model: HLWorkspaceModel new.\x0a\x09\x09model ]",
-messageSends: ["ifNil:", "model:", "new"],
-referencedClasses: ["HLWorkspaceModel"]
+source: "browserModel\x0a\x09^ browserModel",
+messageSends: [],
+referencedClasses: []
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_model_",
+"_browserModel_",
 smalltalk.method({
-selector: "model:",
+selector: "browserModel:",
 category: 'accessing',
-fn: function (aModel){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@model"]=aModel;
-_st(_st(self)._codeWidget())._model_(_st(aModel)._code());
-_st(self)._observeCodeWidget();
-return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel}, smalltalk.HLWorkspace)})},
-args: ["aModel"],
-source: "model: aModel\x0a\x09model := aModel.\x0a     \x0a    self codeWidget model: aModel code.\x0a    self observeCodeWidget.\x0a    ",
-messageSends: ["model:", "code", "codeWidget", "observeCodeWidget"],
+fn: function (aBrowserModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@browserModel"]=aBrowserModel;
+_st(self)._observeBrowserModel();
+return self}, function($ctx1) {$ctx1.fill(self,"browserModel:",{aBrowserModel:aBrowserModel}, smalltalk.HLSourceCodeWidget)})},
+args: ["aBrowserModel"],
+source: "browserModel: aBrowserModel\x0a\x09browserModel := aBrowserModel.\x0a\x09self observeBrowserModel",
+messageSends: ["observeBrowserModel"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_observeCodeWidget",
+"_observeBrowserModel",
 smalltalk.method({
-selector: "observeCodeWidget",
+selector: "observeBrowserModel",
 category: 'actions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"observeCodeWidget",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=_st(_st(self)._browserModel())._announcer();
+_st($1)._on_do_((smalltalk.HLSaveSourceCode || HLSaveSourceCode),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onSaveIt();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLParseErrorRaised || HLParseErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onParseError_(ann);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLCompileErrorRaised || HLCompileErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onCompileError_(_st(ann)._error());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_((smalltalk.HLUnknownVariableErrorRaised || HLUnknownVariableErrorRaised),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onUnknownVariableError_(_st(ann)._error());
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+$2=_st($1)._on_do_((smalltalk.HLInstVarAdded || HLInstVarAdded),(function(ann){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._onInstVarAdded();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeBrowserModel",{}, smalltalk.HLSourceCodeWidget)})},
 args: [],
-source: "observeCodeWidget\x0a\x0a",
-messageSends: [],
-referencedClasses: []
+source: "observeBrowserModel\x0a\x09self browserModel announcer\x0a\x09\x09on: HLSaveSourceCode\x0a\x09\x09do: [ :ann | self onSaveIt ];\x0a\x09\x09on: HLParseErrorRaised\x0a\x09\x09do: [ :ann | self onParseError: ann ];\x0a\x09\x09on: HLCompileErrorRaised\x0a\x09\x09do: [ :ann | self onCompileError: ann error ];\x0a\x09\x09on: HLUnknownVariableErrorRaised\x0a\x09\x09do: [ :ann | self onUnknownVariableError: ann error ];\x0a\x09\x09on: HLInstVarAdded \x0a\x09\x09do: [ :ann | self onInstVarAdded ]",
+messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded"],
+referencedClasses: ["HLSaveSourceCode", "HLParseErrorRaised", "HLCompileErrorRaised", "HLUnknownVariableErrorRaised", "HLInstVarAdded"]
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_onDoIt",
+"_onCompileError_",
 smalltalk.method({
-selector: "onDoIt",
+selector: "onCompileError:",
 category: 'reactions',
-fn: function (){
+fn: function (anError){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onDoIt",{}, smalltalk.HLWorkspace)})},
-args: [],
-source: "onDoIt",
-messageSends: [],
+return smalltalk.withContext(function($ctx1) { 
_st(self)._alert_(_st(anError)._messageText());
+return self}, function($ctx1) {$ctx1.fill(self,"onCompileError:",{anError:anError}, smalltalk.HLSourceCodeWidget)})},
+args: ["anError"],
+source: "onCompileError: anError\x0a\x09self alert: anError messageText",
+messageSends: ["alert:", "messageText"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_onInspectIt",
+"_onInstVarAdded",
 smalltalk.method({
-selector: "onInspectIt",
+selector: "onInstVarAdded",
 category: 'reactions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onInspectIt",{}, smalltalk.HLWorkspace)})},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._save_(_st(self)._contents());
+return self}, function($ctx1) {$ctx1.fill(self,"onInstVarAdded",{}, smalltalk.HLSourceCodeWidget)})},
 args: [],
-source: "onInspectIt",
-messageSends: [],
+source: "onInstVarAdded\x0a\x09self  browserModel save: self contents",
+messageSends: ["save:", "contents", "browserModel"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspace);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_onPrintIt",
+"_onParseError_",
 smalltalk.method({
-selector: "onPrintIt",
+selector: "onParseError:",
 category: 'reactions',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"onPrintIt",{}, smalltalk.HLWorkspace)})},
-args: [],
-source: "onPrintIt",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.HLWorkspace);
-
-smalltalk.addMethod(
-"_renderContentOn_",
-smalltalk.method({
-selector: "renderContentOn:",
-category: 'rendering',
-fn: function (html){
+fn: function (anAnnouncement){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(html)._with_(_st(self)._codeWidget());
-return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html}, smalltalk.HLWorkspace)})},
-args: ["html"],
-source: "renderContentOn: html\x0a\x09html with: self codeWidget\x0a    ",
-messageSends: ["with:", "codeWidget"],
-referencedClasses: []
+var lineIndex,newContents;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3;
+lineIndex=(1);
+_st(self)._contents_(_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
return _st(_st(self)._contents())._linesDo_((function(each){
+return smalltalk.withContext(function($ctx3) {
$1=_st(lineIndex).__eq(_st(anAnnouncement)._line());
+if(smalltalk.assert($1)){
+$2=stream;
+_st($2)._nextPutAll_(_st(each)._copyFrom_to_((1),_st(anAnnouncement)._column()));
+_st($2)._nextPutAll_("<- ");
+_st($2)._nextPutAll_(_st(anAnnouncement)._message());
+_st($2)._nextPutAll_(" ");
+$3=_st($2)._nextPutAll_(_st(each)._copyFrom_to_(_st(_st(anAnnouncement)._column()).__plus((1)),_st(each)._size()));
+$3;
+} else {
+_st(stream)._nextPutAll_(each);
+};
+_st(stream)._nextPutAll_(_st((smalltalk.String || String))._cr());
+lineIndex=_st(lineIndex).__plus((1));
+return lineIndex;
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
+return self}, function($ctx1) {$ctx1.fill(self,"onParseError:",{anAnnouncement:anAnnouncement,lineIndex:lineIndex,newContents:newContents}, smalltalk.HLSourceCodeWidget)})},
+args: ["anAnnouncement"],
+source: "onParseError: anAnnouncement\x0a\x09| lineIndex newContents |\x0a\x09\x0a\x09lineIndex := 1.\x0a\x09\x0a\x09self contents: (String streamContents: [ :stream |\x0a\x09\x09self contents linesDo: [ :each |\x0a\x09\x09\x09lineIndex = anAnnouncement line \x0a\x09\x09\x09\x09ifTrue: [ \x0a\x09\x09\x09\x09\x09stream \x0a\x09\x09\x09\x09\x09\x09nextPutAll: (each copyFrom: 1 to: anAnnouncement column);\x0a\x09\x09\x09\x09\x09\x09nextPutAll: '<- ';\x0a\x09\x09\x09\x09\x09\x09nextPutAll: anAnnouncement message;\x0a\x09\x09\x09\x09\x09\x09nextPutAll: ' ';\x0a\x09\x09\x09\x09\x09\x09nextPutAll: (each copyFrom: anAnnouncement column + 1 to: each size) ]\x0a\x09\x09\x09\x09ifFalse: [ stream nextPutAll: each ].\x0a\x09\x09\x09stream nextPutAll: String cr.\x0a\x09\x09\x09lineIndex := lineIndex + 1 ] ])",
+messageSends: ["contents:", "streamContents:", "linesDo:", "ifTrue:ifFalse:", "nextPutAll:", "copyFrom:to:", "column", "message", "+", "size", "=", "line", "cr", "contents"],
+referencedClasses: ["String"]
 }),
-smalltalk.HLWorkspace);
-
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_canBeOpenAsTab",
+"_onSaveIt",
 smalltalk.method({
-selector: "canBeOpenAsTab",
-category: 'testing',
+selector: "onSaveIt",
+category: 'reactions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return true;
-}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLWorkspace.klass)})},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._save_(_st(self)._contents());
+return self}, function($ctx1) {$ctx1.fill(self,"onSaveIt",{}, smalltalk.HLSourceCodeWidget)})},
 args: [],
-source: "canBeOpenAsTab\x0a\x09^ true",
-messageSends: [],
+source: "onSaveIt\x0a\x09self  browserModel save: self contents",
+messageSends: ["save:", "contents", "browserModel"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspace.klass);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_tabLabel",
+"_onUnknownVariableError_",
 smalltalk.method({
-selector: "tabLabel",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
return "Workspace";
-}, function($ctx1) {$ctx1.fill(self,"tabLabel",{}, smalltalk.HLWorkspace.klass)})},
-args: [],
-source: "tabLabel\x0a\x09^ 'Workspace'",
-messageSends: [],
-referencedClasses: []
+selector: "onUnknownVariableError:",
+category: 'reactions',
+fn: function (anError){
+var self=this;
+var confirm;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4;
+confirm=_st(self)._confirm_(_st((smalltalk.String || String))._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
$1=stream;
+_st($1)._nextPutAll_(_st(anError)._messageText());
+_st($1)._nextPutAll_(_st((smalltalk.String || String))._cr());
+$2=_st($1)._nextPutAll_("Would you like to define an instance variable?");
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
+$3=confirm;
+if(! smalltalk.assert($3)){
+$4=self;
+return $4;
+};
+_st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
+return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError,confirm:confirm}, smalltalk.HLSourceCodeWidget)})},
+args: ["anError"],
+source: "onUnknownVariableError: anError\x0a\x09| confirm |\x0a\x0a\x09confirm := self confirm: (String streamContents: [ :stream |\x0a\x09\x09stream \x0a\x09\x09\x09nextPutAll: anError messageText;\x0a\x09\x09\x09nextPutAll: String cr;\x0a\x09\x09\x09nextPutAll: 'Would you like to define an instance variable?' ]).\x0a\x09\x09\x09\x0a\x09confirm ifFalse: [ ^ self ].\x0a\x09\x0a\x09self browserModel addInstVarNamed: anError variableName",
+messageSends: ["confirm:", "streamContents:", "nextPutAll:", "messageText", "cr", "ifFalse:", "addInstVarNamed:", "variableName", "browserModel"],
+referencedClasses: ["String"]
 }),
-smalltalk.HLWorkspace.klass);
+smalltalk.HLSourceCodeWidget);
 
 smalltalk.addMethod(
-"_tabPriority",
+"_saveIt",
 smalltalk.method({
-selector: "tabPriority",
-category: 'accessing',
+selector: "saveIt",
+category: 'actions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return (10);
-}, function($ctx1) {$ctx1.fill(self,"tabPriority",{}, smalltalk.HLWorkspace.klass)})},
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._browserModel())._saveSourceCode();
+return self}, function($ctx1) {$ctx1.fill(self,"saveIt",{}, smalltalk.HLSourceCodeWidget)})},
 args: [],
-source: "tabPriority\x0a\x09^ 10",
-messageSends: [],
+source: "saveIt\x0a\x09self browserModel saveSourceCode",
+messageSends: ["saveSourceCode", "browserModel"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspace.klass);
-
+smalltalk.HLSourceCodeWidget);
 
-smalltalk.addClass('HLWorkspaceModel', smalltalk.Object, ['announcer', 'environment', 'code'], 'Helios-Workspace');
-smalltalk.addMethod(
-"_announcer",
-smalltalk.method({
-selector: "announcer",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@announcer"];
-if(($receiver = $2) == nil || $receiver == undefined){
-self["@announcer"]=_st((smalltalk.Announcer || Announcer))._new();
-$1=self["@announcer"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"announcer",{}, smalltalk.HLWorkspaceModel)})},
-args: [],
-source: "announcer\x0a\x09^ announcer ifNil: [ announcer := Announcer new ]",
-messageSends: ["ifNil:", "new"],
-referencedClasses: ["Announcer"]
-}),
-smalltalk.HLWorkspaceModel);
 
 smalltalk.addMethod(
-"_code",
-smalltalk.method({
-selector: "code",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@code"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$1=_st((smalltalk.HLCodeModel || HLCodeModel))._on_(_st(self)._environment());
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"code",{}, smalltalk.HLWorkspaceModel)})},
-args: [],
-source: "code\x0a\x09\x22Answers the code model working for this workspace model\x22\x0a\x09^ code ifNil:[ HLCodeModel on: self environment ]",
-messageSends: ["ifNil:", "on:", "environment"],
-referencedClasses: ["HLCodeModel"]
-}),
-smalltalk.HLWorkspaceModel);
-
-smalltalk.addMethod(
-"_environment",
+"_canBeOpenAsTab",
 smalltalk.method({
-selector: "environment",
-category: 'accessing',
+selector: "canBeOpenAsTab",
+category: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $2,$1;
-$2=self["@environment"];
-if(($receiver = $2) == nil || $receiver == undefined){
-$1=_st(_st((smalltalk.HLManager || HLManager))._current())._environment();
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"environment",{}, smalltalk.HLWorkspaceModel)})},
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"canBeOpenAsTab",{}, smalltalk.HLSourceCodeWidget.klass)})},
 args: [],
-source: "environment\x0a\x09^ environment ifNil: [ HLManager current environment ]",
-messageSends: ["ifNil:", "environment", "current"],
-referencedClasses: ["HLManager"]
-}),
-smalltalk.HLWorkspaceModel);
-
-smalltalk.addMethod(
-"_environment_",
-smalltalk.method({
-selector: "environment:",
-category: 'accessing',
-fn: function (anEnvironment){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@environment"]=anEnvironment;
-return self}, function($ctx1) {$ctx1.fill(self,"environment:",{anEnvironment:anEnvironment}, smalltalk.HLWorkspaceModel)})},
-args: ["anEnvironment"],
-source: "environment: anEnvironment\x0a\x09environment := anEnvironment",
+source: "canBeOpenAsTab\x0a\x09^ false",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLWorkspaceModel);
-
-smalltalk.addMethod(
-"_onKeyDown_",
-smalltalk.method({
-selector: "onKeyDown:",
-category: 'reactions',
-fn: function (anEvent){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
if(anEvent.ctrlKey) {
-		if(anEvent.keyCode === 80) { //ctrl+p
-			self._printIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 68) { //ctrl+d
-			self._doIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 73) { //ctrl+i
-			self._inspectIt();
-			anEvent.preventDefault();
-			return false;
-		}
-	};
-return self}, function($ctx1) {$ctx1.fill(self,"onKeyDown:",{anEvent:anEvent}, smalltalk.HLWorkspaceModel)})},
-args: ["anEvent"],
-source: "onKeyDown: anEvent\x0a\x0a\x09<if(anEvent.ctrlKey) {\x0a\x09\x09if(anEvent.keyCode === 80) { //ctrl+p\x0a\x09\x09\x09self._printIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 68) { //ctrl+d\x0a\x09\x09\x09self._doIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09\x09if(anEvent.keyCode === 73) { //ctrl+i\x0a\x09\x09\x09self._inspectIt();\x0a\x09\x09\x09anEvent.preventDefault();\x0a\x09\x09\x09return false;\x0a\x09\x09}\x0a\x09}>",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.HLWorkspaceModel);
-
+smalltalk.HLSourceCodeWidget.klass);
 
 smalltalk.addMethod(
 "_on_",
 smalltalk.method({
 selector: "on:",
-category: 'actions',
-fn: function (anEnvironment){
+category: 'instance creation',
+fn: function (aBrowserModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$1;
 $2=_st(self)._new();
-_st($2)._environment_(anEnvironment);
+_st($2)._browserModel_(aBrowserModel);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{anEnvironment:anEnvironment}, smalltalk.HLWorkspaceModel.klass)})},
-args: ["anEnvironment"],
-source: "on: anEnvironment\x0a\x0a\x09^ self new\x0a    \x09environment: anEnvironment;\x0a        yourself",
-messageSends: ["environment:", "new", "yourself"],
+}, function($ctx1) {$ctx1.fill(self,"on:",{aBrowserModel:aBrowserModel}, smalltalk.HLSourceCodeWidget.klass)})},
+args: ["aBrowserModel"],
+source: "on: aBrowserModel\x0a\x09^ self new\x0a\x09\x09browserModel: aBrowserModel;\x0a\x09\x09yourself",
+messageSends: ["browserModel:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLWorkspaceModel.klass);
+smalltalk.HLSourceCodeWidget.klass);
 
 

+ 78 - 0
st/Helios-Announcements.st

@@ -48,6 +48,58 @@ HLAnnouncement subclass: #HLDiveRequested
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!
 
+HLAnnouncement subclass: #HLErrorRaised
+	instanceVariableNames: 'error'
+	package: 'Helios-Announcements'!
+
+!HLErrorRaised methodsFor: 'accessing'!
+
+error
+	^ error
+!
+
+error: anError
+	error := anError
+! !
+
+HLErrorRaised subclass: #HLCompileErrorRaised
+	instanceVariableNames: ''
+	package: 'Helios-Announcements'!
+
+HLErrorRaised subclass: #HLParseErrorRaised
+	instanceVariableNames: 'line column message'
+	package: 'Helios-Announcements'!
+
+!HLParseErrorRaised methodsFor: 'accessing'!
+
+column
+	^ column
+!
+
+column: anInteger
+	column := anInteger
+!
+
+line
+	^ line
+!
+
+line: anInteger
+	line := anInteger
+!
+
+message
+	^ message
+!
+
+message: aString
+	message := aString
+! !
+
+HLErrorRaised subclass: #HLUnknownVariableErrorRaised
+	instanceVariableNames: ''
+	package: 'Helios-Announcements'!
+
 HLAnnouncement subclass: #HLFocusRequested
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!
@@ -72,6 +124,28 @@ HLFocusRequested subclass: #HLSourceCodeFocusRequested
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!
 
+HLAnnouncement subclass: #HLInstVarAdded
+	instanceVariableNames: 'theClass variableName'
+	package: 'Helios-Announcements'!
+
+!HLInstVarAdded methodsFor: 'accessing'!
+
+theClass
+	^ theClass
+!
+
+theClass: aClass
+	theClass := aClass
+!
+
+variableName
+	^ variableName
+!
+
+variableName: aString
+	variableName := aString
+! !
+
 HLAnnouncement subclass: #HLItemSelected
 	instanceVariableNames: 'item'
 	package: 'Helios-Announcements'!
@@ -118,6 +192,10 @@ HLAnnouncement subclass: #HLRefreshRequested
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!
 
+HLAnnouncement subclass: #HLSaveSourceCode
+	instanceVariableNames: ''
+	package: 'Helios-Announcements'!
+
 HLAnnouncement subclass: #HLShowCommentToggled
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!

+ 127 - 6
st/Helios-Browser.st

@@ -686,10 +686,6 @@ Object subclass: #HLBrowserModel
 
 !HLBrowserModel methodsFor: 'accessing'!
 
-allProtocol
-	^ '-- All --'
-!
-
 announcer
 	^ announcer ifNil: [ announcer := Announcer new ]
 !
@@ -711,7 +707,9 @@ selectedClass
 !
 
 selectedClass: aClass
-	selectedClass = aClass ifTrue: [ ^ self ].
+	selectedClass = aClass ifTrue: [ 
+		aClass ifNil: [ ^ self ].
+		self selectedProtocol: nil ].
     
 	aClass 
    		ifNil: [ selectedClass := nil ]
@@ -791,6 +789,14 @@ showInstance: aBoolean
 
 !HLBrowserModel methodsFor: 'actions'!
 
+addInstVarNamed: aString
+	self environment addInstVarNamed: aString to: self selectedClass.
+	self announcer announce: (HLInstVarAdded new
+		theClass: self selectedClass;
+		variableName: aString;
+		yourself)
+!
+
 focusOnClasses
 	self announcer announce: HLClassesFocusRequested new
 !
@@ -809,6 +815,121 @@ focusOnProtocols
 
 focusOnSourceCode
 	self announcer announce: HLSourceCodeFocusRequested new
+!
+
+save: aString
+	self shouldCompileClassDefinition 
+		ifTrue: [ self compileClassDefinition: aString ]
+		ifFalse: [ 
+			self shouldCompileClassComment 
+				ifTrue: [ self compileClassComment: aString ]
+				ifFalse: [ self compileMethod: aString ] ]
+!
+
+saveSourceCode
+	self announcer announce: HLSaveSourceCode new
+! !
+
+!HLBrowserModel methodsFor: 'compiling'!
+
+compileClassComment: aString
+	self environment 
+		compileClassComment: aString 
+		for: self selectedClass
+!
+
+compileClassDefinition: aString
+	self environment compileClassDefinition: aString
+!
+
+compileMethod: aString
+	self withCompileErrorHandling: [ self environment 
+		compileMethod: aString 
+		for: self selectedClass
+		protocol: self compilationProtocol ]
+! !
+
+!HLBrowserModel methodsFor: 'defaults'!
+
+allProtocol
+	^ '-- All --'
+!
+
+unclassifiedProtocol
+	^ 'as yet unclassified'
+! !
+
+!HLBrowserModel methodsFor: 'error handling'!
+
+handleCompileError: anError
+	self announcer announce: (HLCompileErrorRaised new
+		error: anError;
+		yourself)
+!
+
+handleParseError: anError
+	| split line column messageToInsert |
+	
+	split := anError messageText tokenize: ' : '.
+	messageToInsert := split second.
+
+	"21 = 'Parse error on line ' size + 1"
+	split := split first copyFrom: 21 to: split first size.
+	
+	split := split tokenize: ' column '.
+	line := split first.
+	column := split second.
+	
+	self announcer announce: (HLParseErrorRaised new
+		line: line asNumber;
+		column: column asNumber;
+		message: messageToInsert;
+		error: anError;
+		yourself)
+!
+
+handleUnkownVariableError: anError
+	self announcer announce: (HLUnknownVariableErrorRaised new
+		error: anError;
+		yourself)
+!
+
+withCompileErrorHandling: aBlock
+	[
+		[
+			aBlock 
+				on: ParseError
+				do: [:ex | self handleParseError: ex ]
+		]
+			on: UnknownVariableError
+			do: [ :ex | self handleUnkownVariableError: ex ]
+	]
+		on: CompilerError
+		do: [ :ex | self handleCompileError: ex ]
+! !
+
+!HLBrowserModel methodsFor: 'private'!
+
+compilationProtocol
+	| currentProtocol |
+	
+	currentProtocol := self selectedProtocol.
+
+	^ currentProtocol = self allProtocol
+		ifTrue: [ self unclassifiedProtocol ]
+		ifFalse: [ currentProtocol ]
+! !
+
+!HLBrowserModel methodsFor: 'testing'!
+
+shouldCompileClassComment
+	"TODO"
+	
+	^ false
+!
+
+shouldCompileClassDefinition
+	^ self selectedProtocol isNil
 ! !
 
 !HLBrowserModel class methodsFor: 'actions'!
@@ -827,7 +948,7 @@ HLWidget subclass: #HLBrowserSourceWidget
 !HLBrowserSourceWidget methodsFor: 'accessing'!
 
 codeWidget
-	^ codeWidget ifNil: [ codeWidget := HLCodeWidget new ]
+	^ codeWidget ifNil: [ codeWidget := HLSourceCodeWidget on: self model ]
 !
 
 contents

+ 10 - 0
st/Helios-Core.st

@@ -62,6 +62,16 @@ wrapper
 	^ wrapper
 ! !
 
+!HLWidget methodsFor: 'actions'!
+
+alert: aString
+	window alert: aString
+!
+
+confirm: aString
+	^ window confirm: aString
+! !
+
 !HLWidget methodsFor: 'keybindings'!
 
 registerBindings

+ 32 - 2
st/Helios-Environments.st

@@ -7,8 +7,11 @@ Abstract class defining common behavior for local and remote environments!
 
 !HLEnvironment methodsFor: 'accessing'!
 
-packages
+classBuilder
+	^ self subclassResponsibility
+!
 
+packages
 	^ self subclassResponsibility
 ! !
 
@@ -19,14 +22,41 @@ eval: someCode on: aReceiver
 	^ self subclassResponsibility
 ! !
 
+!HLEnvironment methodsFor: 'compiling'!
+
+addInstVarNamed: aString to: aClass
+	self classBuilder
+		addSubclassOf: aClass superclass 
+		named: aClass name 
+		instanceVariableNames: (aClass instanceVariableNames copy add: aString; yourself)
+		package: aClass package name
+!
+
+compileClassComment: aString for: aClass
+	aClass comment: aString
+!
+
+compileClassDefinition: aString
+	self eval: aString on: DoIt new
+!
+
+compileMethod: sourceCode for: class protocol: protocol
+	class
+		compile: sourceCode
+		category: protocol
+! !
+
 HLEnvironment subclass: #HLLocalEnvironment
 	instanceVariableNames: ''
 	package: 'Helios-Environments'!
 
 !HLLocalEnvironment methodsFor: 'accessing'!
 
-packages
+classBuilder
+	^ ClassBuilder new
+!
 
+packages
 	^ Smalltalk current packages
 ! !
 

+ 81 - 110
st/Helios-Workspace.st

@@ -80,9 +80,7 @@ currentLineOrSelection
 !
 
 model
-	^ model ifNil: [ 
-    	self model: HLCodeModel new.
-		model ]
+	^ model ifNil: [ model := HLCodeModel new ]
 !
 
 model: aModel
@@ -307,6 +305,14 @@ pcKeyMap
 		'Shift-Ctrl-Z' -> 'redo'. 
 		'fallthrough' -> #('basic')
 }
+!
+
+tabLabel
+	^ 'Workspace'
+!
+
+tabPriority
+	^ 10
 ! !
 
 !HLCodeWidget class methodsFor: 'initialization'!
@@ -335,141 +341,106 @@ setupKeyMaps
 	<CodeMirror.keyMap['Amber'] = self._keyMap()>
 ! !
 
-HLCodeWidget subclass: #HLSourceCodeWidget
-	instanceVariableNames: ''
-	package: 'Helios-Workspace'!
-
-!HLSourceCodeWidget methodsFor: 'reactions'!
-
-onKeyDown: anEvent
-	(super onKeyDown: anEvent) ifFalse: [ ^ false ].
-    
-	anEvent ctrlKey ifTrue: [
-		anEvent keyCode = 83 ifTrue: [
-			self onSave.
-			anEvent preventDefault.
-			^ false ] ]
-!
+!HLCodeWidget class methodsFor: 'testing'!
 
-onSave
+canBeOpenAsTab
+	^ true
 ! !
 
-HLWidget subclass: #HLWorkspace
-	instanceVariableNames: 'model codeWidget'
+HLCodeWidget subclass: #HLSourceCodeWidget
+	instanceVariableNames: 'browserModel'
 	package: 'Helios-Workspace'!
 
-!HLWorkspace methodsFor: 'accessing'!
+!HLSourceCodeWidget methodsFor: 'accessing'!
 
-codeWidget
-	^ codeWidget ifNil: [
-		codeWidget := HLCodeWidget new
-    		model: self model code;
-        	yourself ]
+browserModel
+	^ browserModel
 !
 
-model
-	^ model ifNil: [ 
-    	self model: HLWorkspaceModel new.
-		model ]
-!
-
-model: aModel
-	model := aModel.
-     
-    self codeWidget model: aModel code.
-    self observeCodeWidget.
+browserModel: aBrowserModel
+	browserModel := aBrowserModel.
+	self observeBrowserModel
 ! !
 
-!HLWorkspace methodsFor: 'actions'!
-
-observeCodeWidget
-! !
+!HLSourceCodeWidget methodsFor: 'actions'!
 
-!HLWorkspace methodsFor: 'reactions'!
-
-onDoIt
+observeBrowserModel
+	self browserModel announcer
+		on: HLSaveSourceCode
+		do: [ :ann | self onSaveIt ];
+		on: HLParseErrorRaised
+		do: [ :ann | self onParseError: ann ];
+		on: HLCompileErrorRaised
+		do: [ :ann | self onCompileError: ann error ];
+		on: HLUnknownVariableErrorRaised
+		do: [ :ann | self onUnknownVariableError: ann error ];
+		on: HLInstVarAdded 
+		do: [ :ann | self onInstVarAdded ]
 !
 
-onInspectIt
-!
-
-onPrintIt
-! !
-
-!HLWorkspace methodsFor: 'rendering'!
-
-renderContentOn: html
-	html with: self codeWidget
+saveIt
+	self browserModel saveSourceCode
 ! !
 
-!HLWorkspace class methodsFor: 'accessing'!
+!HLSourceCodeWidget methodsFor: 'reactions'!
 
-tabLabel
-	^ 'Workspace'
+onCompileError: anError
+	self alert: anError messageText
 !
 
-tabPriority
-	^ 10
-! !
-
-!HLWorkspace class methodsFor: 'testing'!
-
-canBeOpenAsTab
-	^ true
-! !
-
-Object subclass: #HLWorkspaceModel
-	instanceVariableNames: 'announcer environment code'
-	package: 'Helios-Workspace'!
-
-!HLWorkspaceModel methodsFor: 'accessing'!
-
-announcer
-	^ announcer ifNil: [ announcer := Announcer new ]
+onInstVarAdded
+	self  browserModel save: self contents
 !
 
-code
-	"Answers the code model working for this workspace model"
-	^ code ifNil:[ HLCodeModel on: self environment ]
+onParseError: anAnnouncement
+	| lineIndex newContents |
+	
+	lineIndex := 1.
+	
+	self contents: (String streamContents: [ :stream |
+		self contents linesDo: [ :each |
+			lineIndex = anAnnouncement line 
+				ifTrue: [ 
+					stream 
+						nextPutAll: (each copyFrom: 1 to: anAnnouncement column);
+						nextPutAll: '<- ';
+						nextPutAll: anAnnouncement message;
+						nextPutAll: ' ';
+						nextPutAll: (each copyFrom: anAnnouncement column + 1 to: each size) ]
+				ifFalse: [ stream nextPutAll: each ].
+			stream nextPutAll: String cr.
+			lineIndex := lineIndex + 1 ] ])
 !
 
-environment
-	^ environment ifNil: [ HLManager current environment ]
+onSaveIt
+	self  browserModel save: self contents
 !
 
-environment: anEnvironment
-	environment := anEnvironment
-! !
+onUnknownVariableError: anError
+	| confirm |
 
-!HLWorkspaceModel methodsFor: 'reactions'!
-
-onKeyDown: anEvent
-
-	<if(anEvent.ctrlKey) {
-		if(anEvent.keyCode === 80) { //ctrl+p
-			self._printIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 68) { //ctrl+d
-			self._doIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 73) { //ctrl+i
-			self._inspectIt();
-			anEvent.preventDefault();
-			return false;
-		}
-	}>
+	confirm := self confirm: (String streamContents: [ :stream |
+		stream 
+			nextPutAll: anError messageText;
+			nextPutAll: String cr;
+			nextPutAll: 'Would you like to define an instance variable?' ]).
+			
+	confirm ifFalse: [ ^ self ].
+	
+	self browserModel addInstVarNamed: anError variableName
 ! !
 
-!HLWorkspaceModel class methodsFor: 'actions'!
-
-on: anEnvironment
+!HLSourceCodeWidget class methodsFor: 'instance creation'!
 
+on: aBrowserModel
 	^ self new
-    	environment: anEnvironment;
-        yourself
+		browserModel: aBrowserModel;
+		yourself
+! !
+
+!HLSourceCodeWidget class methodsFor: 'testing'!
+
+canBeOpenAsTab
+	^ false
 ! !