浏览代码

Adds support for generating methods in Helios

- Supports `initialize`
- Supports `getter`/`setter`
- Dispatches the generation stategy to the selected class
Benjamin Van Ryseghem 11 年之前
父节点
当前提交
fa18b27703
共有 7 个文件被更改,包括 1326 次插入0 次删除
  1. 168 0
      js/Helios-Commands-Browser.js
  2. 705 0
      js/Helios-Helpers.js
  3. 80 0
      js/Kernel-Objects.js
  4. 82 0
      st/Helios-Commands-Browser.st
  5. 270 0
      st/Helios-Helpers.st
  6. 20 0
      st/Kernel-Objects.st
  7. 1 0
      support/helios.js

+ 168 - 0
js/Helios-Commands-Browser.js

@@ -406,6 +406,174 @@ referencedClasses: []
 smalltalk.HLEditCommentCommand.klass);
 smalltalk.HLEditCommentCommand.klass);
 
 
 
 
+smalltalk.addClass('HLGenerateCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
+smalltalk.HLGenerateCommand.comment="I am a group command used to gather all the commands generating code (`accessors`, `initialize`, etc)";
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "h";
+}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGenerateCommand.klass)})},
+args: [],
+source: "key\x0a\x09^ 'h'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "Generate";
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGenerateCommand.klass)})},
+args: [],
+source: "label\x0a\x09^ 'Generate'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateCommand.klass);
+
+
+smalltalk.addClass('HLGenerateAccessorsCommand', smalltalk.HLGenerateCommand, [], 'Helios-Commands-Browser');
+smalltalk.HLGenerateAccessorsCommand.comment="I am the command used to generate the `initialize` method depending of the selected class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
+fn: function (){
+var self=this;
+var targetClass,output,first;
+function $HLInitializeGenerator(){return smalltalk.HLInitializeGenerator||(typeof HLInitializeGenerator=="undefined"?nil:HLInitializeGenerator)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5;
+$1=self._model();
+$ctx1.sendIdx["model"]=1;
+targetClass=_st($1)._selectedClass();
+$2=_st($HLInitializeGenerator())._new();
+_st($2)._class_(targetClass);
+_st($2)._generate();
+$3=_st($2)._output();
+output=$3;
+_st(output)._serialize();
+first=_st(_st(output)._sourceCodes())._first();
+$4=self._model();
+_st($4)._selectedProtocol_(_st(output)._protocol());
+_st($4)._selectedMethod_(_st(targetClass).__gt_gt(_st(first)._selector()));
+$5=_st($4)._focusOnSourceCode();
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{targetClass:targetClass,output:output,first:first},smalltalk.HLGenerateAccessorsCommand)})},
+args: [],
+source: "execute\x0a\x09| targetClass output first |\x0a\x09targetClass := self model selectedClass.\x0a\x0a\x09output := HLInitializeGenerator new\x0a\x09\x09class: targetClass;\x0a\x09\x09generate;\x0a\x09\x09output.\x0a\x09\x09\x0a\x09output serialize.\x0a\x09first := output sourceCodes first.\x0a\x09self model\x0a\x09\x09selectedProtocol: output protocol;\x0a\x09\x09selectedMethod:(targetClass>>first selector);\x0a\x09\x09focusOnSourceCode",
+messageSends: ["selectedClass", "model", "class:", "new", "generate", "output", "serialize", "first", "sourceCodes", "selectedProtocol:", "protocol", "selectedMethod:", ">>", "selector", "focusOnSourceCode"],
+referencedClasses: ["HLInitializeGenerator"]
+}),
+smalltalk.HLGenerateAccessorsCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "i";
+}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGenerateAccessorsCommand.klass)})},
+args: [],
+source: "key\x0a\x09^ 'i'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateAccessorsCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "Initialize";
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGenerateAccessorsCommand.klass)})},
+args: [],
+source: "label\x0a\x09^ 'Initialize'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateAccessorsCommand.klass);
+
+
+smalltalk.addClass('HLGenerateInitializeCommand', smalltalk.HLGenerateCommand, [], 'Helios-Commands-Browser');
+smalltalk.HLGenerateInitializeCommand.comment="I am the command used to generate the `gettet` and the `setter` methods depending of the selected class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
+fn: function (){
+var self=this;
+var targetClass,output;
+function $HLAccessorsGenerator(){return smalltalk.HLAccessorsGenerator||(typeof HLAccessorsGenerator=="undefined"?nil:HLAccessorsGenerator)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+$1=self._model();
+$ctx1.sendIdx["model"]=1;
+targetClass=_st($1)._selectedClass();
+$2=_st($HLAccessorsGenerator())._new();
+_st($2)._class_(targetClass);
+_st($2)._generate();
+$3=_st($2)._output();
+output=$3;
+_st(output)._serialize();
+_st(self._model())._selectedProtocol_(_st(output)._protocol());
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{targetClass:targetClass,output:output},smalltalk.HLGenerateInitializeCommand)})},
+args: [],
+source: "execute\x0a\x09| targetClass output |\x0a\x09targetClass := self model selectedClass.\x0a\x0a\x09output := HLAccessorsGenerator new\x0a\x09\x09class: targetClass;\x0a\x09\x09generate;\x0a\x09\x09output.\x0a\x09\x09\x0a\x09output serialize.\x0a\x09self model selectedProtocol: output protocol",
+messageSends: ["selectedClass", "model", "class:", "new", "generate", "output", "serialize", "selectedProtocol:", "protocol"],
+referencedClasses: ["HLAccessorsGenerator"]
+}),
+smalltalk.HLGenerateInitializeCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "a";
+}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGenerateInitializeCommand.klass)})},
+args: [],
+source: "key\x0a\x09^ 'a'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateInitializeCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "Accessors";
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGenerateInitializeCommand.klass)})},
+args: [],
+source: "label\x0a\x09^ 'Accessors'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerateInitializeCommand.klass);
+
+
 smalltalk.addClass('HLToggleCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
 smalltalk.addClass('HLToggleCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
 
 
 smalltalk.addMethod(
 smalltalk.addMethod(

+ 705 - 0
js/Helios-Helpers.js

@@ -0,0 +1,705 @@
+define("amber_core/Helios-Helpers", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+smalltalk.addPackage('Helios-Helpers');
+smalltalk.packages["Helios-Helpers"].transport = {"type":"amd","amdNamespace":"amber_core"};
+
+smalltalk.addClass('HLGenerationOutput', smalltalk.Object, ['sourceCodes', 'protocol', 'targetClass'], 'Helios-Helpers');
+smalltalk.HLGenerationOutput.comment="I am a simple data object used to store the result of a generation process";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addSourceCode:",
+protocol: 'protocol',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@sourceCodes"])._add_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"addSourceCode:",{aString:aString},smalltalk.HLGenerationOutput)})},
+args: ["aString"],
+source: "addSourceCode: aString\x0a\x09sourceCodes add: aString",
+messageSends: ["add:"],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.HLGenerationOutput.superclass.fn.prototype._initialize.apply(_st(self), []);
+self["@sourceCodes"]=_st($OrderedCollection())._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLGenerationOutput)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09sourceCodes := OrderedCollection new",
+messageSends: ["initialize", "new"],
+referencedClasses: ["OrderedCollection"]
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "protocol",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@protocol"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"protocol",{},smalltalk.HLGenerationOutput)})},
+args: [],
+source: "protocol\x0a\x09^ protocol",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "protocol:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@protocol"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"protocol:",{aString:aString},smalltalk.HLGenerationOutput)})},
+args: ["aString"],
+source: "protocol: aString\x0a\x09protocol := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "serialize",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(self["@sourceCodes"])._do_((function(methodSourceCode){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(self["@targetClass"])._includesSelector_(_st(methodSourceCode)._selector());
+if(! smalltalk.assert($1)){
+return _st(self["@targetClass"])._compile_protocol_(_st(methodSourceCode)._sourceCode(),self["@protocol"]);
+};
+}, function($ctx2) {$ctx2.fillBlock({methodSourceCode:methodSourceCode},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"serialize",{},smalltalk.HLGenerationOutput)})},
+args: [],
+source: "serialize\x0a\x09sourceCodes do: [ :methodSourceCode |\x0a\x09\x09(targetClass includesSelector: methodSourceCode selector)\x0a\x09\x09\x09ifFalse: [ \x0a\x09\x09\x09\x09targetClass \x0a\x09\x09\x09\x09\x09compile: methodSourceCode sourceCode\x0a\x09\x09\x09\x09\x09protocol: protocol ] ]",
+messageSends: ["do:", "ifFalse:", "includesSelector:", "selector", "compile:protocol:", "sourceCode"],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCodes",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@sourceCodes"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"sourceCodes",{},smalltalk.HLGenerationOutput)})},
+args: [],
+source: "sourceCodes\x0a\x09^ sourceCodes",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCodes:",
+protocol: 'accessing',
+fn: function (aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@sourceCodes"]=aCollection;
+return self}, function($ctx1) {$ctx1.fill(self,"sourceCodes:",{aCollection:aCollection},smalltalk.HLGenerationOutput)})},
+args: ["aCollection"],
+source: "sourceCodes: aCollection\x0a\x09sourceCodes := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClass",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@targetClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClass",{},smalltalk.HLGenerationOutput)})},
+args: [],
+source: "targetClass\x0a\x09^ targetClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClass:",
+protocol: 'accessing',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@targetClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"targetClass:",{aClass:aClass},smalltalk.HLGenerationOutput)})},
+args: ["aClass"],
+source: "targetClass: aClass\x0a\x09targetClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutput);
+
+
+
+smalltalk.addClass('HLGenerationOutputWithIndex', smalltalk.HLGenerationOutput, ['index'], 'Helios-Helpers');
+smalltalk.HLGenerationOutputWithIndex.comment="I am a simple data object used to store the result of a generation process.\x0a\x0aIn addition of my super class, I have an index where to put the cursor at the end of the process for the first method created (aka. the first in `sourceCodes`)";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "index",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@index"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"index",{},smalltalk.HLGenerationOutputWithIndex)})},
+args: [],
+source: "index\x0a\x09^ index",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutputWithIndex);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "index:",
+protocol: 'accessing',
+fn: function (anIndex){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@index"]=anIndex;
+return self}, function($ctx1) {$ctx1.fill(self,"index:",{anIndex:anIndex},smalltalk.HLGenerationOutputWithIndex)})},
+args: ["anIndex"],
+source: "index: anIndex\x0a\x09index := anIndex",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerationOutputWithIndex);
+
+
+
+smalltalk.addClass('HLGenerator', smalltalk.Object, ['output'], 'Helios-Helpers');
+smalltalk.HLGenerator.comment="I am the abstract super class of the generators.\x0a\x0aMy main method is `generate` which produce an `output` object";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "class:",
+protocol: 'accessing',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._targetClass_(aClass);
+return self}, function($ctx1) {$ctx1.fill(self,"class:",{aClass:aClass},smalltalk.HLGenerator)})},
+args: ["aClass"],
+source: "class: aClass\x0a\x09output targetClass: aClass",
+messageSends: ["targetClass:"],
+referencedClasses: []
+}),
+smalltalk.HLGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self["@output"])._targetClass();
+if(($receiver = $1) == nil || $receiver == null){
+self._error_("class should not be nil");
+} else {
+$1;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},smalltalk.HLGenerator)})},
+args: [],
+source: "generate\x0a\x0a\x09output targetClass ifNil: [ self error: 'class should not be nil'].",
+messageSends: ["ifNil:", "targetClass", "error:"],
+referencedClasses: []
+}),
+smalltalk.HLGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $HLGenerationOutput(){return smalltalk.HLGenerationOutput||(typeof HLGenerationOutput=="undefined"?nil:HLGenerationOutput)}
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.HLGenerator.superclass.fn.prototype._initialize.apply(_st(self), []);
+self["@output"]=_st($HLGenerationOutput())._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLGenerator)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09output := HLGenerationOutput new",
+messageSends: ["initialize", "new"],
+referencedClasses: ["HLGenerationOutput"]
+}),
+smalltalk.HLGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "output",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@output"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"output",{},smalltalk.HLGenerator)})},
+args: [],
+source: "output\x0a\x09^ output",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLGenerator);
+
+
+
+smalltalk.addClass('HLAccessorsGenerator', smalltalk.HLGenerator, [], 'Helios-Helpers');
+smalltalk.HLAccessorsGenerator.comment="I am a generator used to compile the getters/setters of a class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorProtocolForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._protocol_("accessing");
+return self}, function($ctx1) {$ctx1.fill(self,"accessorProtocolForObject",{},smalltalk.HLAccessorsGenerator)})},
+args: [],
+source: "accessorProtocolForObject\x0a\x09output protocol: 'accessing'",
+messageSends: ["protocol:"],
+referencedClasses: []
+}),
+smalltalk.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorsSourceCodesForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+var sources;
+function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+sources=_st($OrderedCollection())._new();
+_st(_st(_st(_st(self["@output"])._targetClass())._instanceVariableNames())._sorted())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=sources;
+_st($1)._add_(self._getterFor_(each));
+$ctx2.sendIdx["add:"]=1;
+$2=_st($1)._add_(self._setterFor_(each));
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+_st(self["@output"])._sourceCodes_(sources);
+return self}, function($ctx1) {$ctx1.fill(self,"accessorsSourceCodesForObject",{sources:sources},smalltalk.HLAccessorsGenerator)})},
+args: [],
+source: "accessorsSourceCodesForObject\x0a\x09| sources |\x0a\x09\x0a\x09sources := OrderedCollection new.\x0a\x09output targetClass instanceVariableNames sorted do: [ :each | \x0a\x09\x09sources \x0a\x09\x09\x09add: (self getterFor: each);\x0a\x09\x09\x09add: (self setterFor: each) ].\x0a\x09output sourceCodes: sources",
+messageSends: ["new", "do:", "sorted", "instanceVariableNames", "targetClass", "add:", "getterFor:", "setterFor:", "sourceCodes:"],
+referencedClasses: ["OrderedCollection"]
+}),
+smalltalk.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+smalltalk.HLAccessorsGenerator.superclass.fn.prototype._generate.apply(_st(self), []);
+$1=_st(self["@output"])._targetClass();
+_st($1)._accessorsSourceCodesWith_(self);
+$2=_st($1)._accessorProtocolWith_(self);
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},smalltalk.HLAccessorsGenerator)})},
+args: [],
+source: "generate\x0a\x09super generate.\x0a\x09\x0a\x09output targetClass \x0a\x09\x09accessorsSourceCodesWith: self;\x0a\x09\x09accessorProtocolWith: self",
+messageSends: ["generate", "accessorsSourceCodesWith:", "targetClass", "accessorProtocolWith:"],
+referencedClasses: []
+}),
+smalltalk.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "getterFor:",
+protocol: 'private',
+fn: function (anInstanceVariable){
+var self=this;
+function $HLMethodSourceCode(){return smalltalk.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$4,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_(anInstanceVariable);
+$3=_st($2)._sourceCode_(_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
+_st(stream).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=1;
+$4=_st(_st(stream)._cr())._cr();
+$ctx2.sendIdx["cr"]=1;
+_st($4)._tab();
+return _st(_st(stream).__lt_lt("^ ")).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=2;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)})})));
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"getterFor:",{anInstanceVariable:anInstanceVariable},smalltalk.HLAccessorsGenerator)})},
+args: ["anInstanceVariable"],
+source: "getterFor: anInstanceVariable\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector:anInstanceVariable;\x0a\x09\x09sourceCode: (String streamContents: [ :stream |\x0a\x09\x09stream << anInstanceVariable.\x0a\x09\x09stream cr cr tab.\x0a\x09\x09stream << '^ ' << anInstanceVariable ])",
+messageSends: ["selector:", "new", "sourceCode:", "streamContents:", "<<", "tab", "cr"],
+referencedClasses: ["HLMethodSourceCode", "String"]
+}),
+smalltalk.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setterFor:",
+protocol: 'private',
+fn: function (anInstanceVariable){
+var self=this;
+function $HLMethodSourceCode(){return smalltalk.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$4,$5,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_(_st(anInstanceVariable).__comma(":"));
+$3=_st($2)._sourceCode_(_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
+$4=_st(stream).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=2;
+_st($4).__lt_lt(": anObject");
+$ctx2.sendIdx["<<"]=1;
+$5=_st(_st(stream)._cr())._cr();
+$ctx2.sendIdx["cr"]=1;
+_st($5)._tab();
+return _st(_st(stream).__lt_lt(anInstanceVariable)).__lt_lt(" := anObject");
+$ctx2.sendIdx["<<"]=3;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)})})));
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"setterFor:",{anInstanceVariable:anInstanceVariable},smalltalk.HLAccessorsGenerator)})},
+args: ["anInstanceVariable"],
+source: "setterFor: anInstanceVariable\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector: anInstanceVariable, ':';\x0a\x09\x09sourceCode: (String streamContents: [ :stream |\x0a\x09\x09stream << anInstanceVariable << ': anObject'.\x0a\x09\x09stream cr cr tab.\x0a\x09\x09stream << anInstanceVariable << ' := anObject' ])",
+messageSends: ["selector:", "new", ",", "sourceCode:", "streamContents:", "<<", "tab", "cr"],
+referencedClasses: ["HLMethodSourceCode", "String"]
+}),
+smalltalk.HLAccessorsGenerator);
+
+
+
+smalltalk.addClass('HLInitializeGenerator', smalltalk.HLGenerator, [], 'Helios-Helpers');
+smalltalk.HLInitializeGenerator.comment="I am used to double-dispatch the `initialize` method(s) generation.\x0a\x0aUsage:\x0a\x0a    ^ HLInitializeGenerator new\x0a        class: aClass;\x0a        generate;\x0a        output\x0a\x0aI am a disposable object";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "computeIndexForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+var instVars,headerSize,firstInstVarSize;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+headerSize=(32);
+instVars=_st(_st(self["@output"])._targetClass())._instanceVariableNames();
+firstInstVarSize=_st(_st(instVars)._sorted())._ifEmpty_ifNotEmpty_((function(){
+return smalltalk.withContext(function($ctx2) {
+return (0);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(_st(instVars)._first())._size()).__plus((4));
+$ctx2.sendIdx["+"]=1;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+$1=_st(headerSize).__plus(firstInstVarSize);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"computeIndexForObject",{instVars:instVars,headerSize:headerSize,firstInstVarSize:firstInstVarSize},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "computeIndexForObject\x0a\x09| instVars headerSize firstInstVarSize |\x0a\x09\x0a\x09\x2232 is the size of the `initiliaze super initialize` part\x22\x0a\x09headerSize := 32.\x0a\x09instVars := output targetClass instanceVariableNames.\x0a\x09firstInstVarSize := instVars sorted\x0a\x09\x09ifEmpty: [ 0 ]\x0a\x09\x09ifNotEmpty:[ instVars first size  + 4 ].\x0a\x09^ headerSize + firstInstVarSize",
+messageSends: ["instanceVariableNames", "targetClass", "ifEmpty:ifNotEmpty:", "sorted", "+", "size", "first"],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+smalltalk.HLInitializeGenerator.superclass.fn.prototype._generate.apply(_st(self), []);
+$1=_st(self["@output"])._targetClass();
+_st($1)._initializeSourceCodesWith_(self);
+_st($1)._initializeIndexWith_(self);
+$2=_st($1)._initializeProtocolWith_(self);
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "generate\x0a\x09super generate.\x0a\x09\x0a\x09output targetClass \x0a\x09\x09initializeSourceCodesWith: self;\x0a\x09\x09initializeIndexWith: self;\x0a\x09\x09initializeProtocolWith: self",
+messageSends: ["generate", "initializeSourceCodesWith:", "targetClass", "initializeIndexWith:", "initializeProtocolWith:"],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generateInitializeCodeForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $3,$2,$4,$5,$6,$7,$8,$1;
+$1=_st($String())._streamContents_((function(str){
+var instVars,size;
+return smalltalk.withContext(function($ctx2) {
+instVars=_st(_st(_st(self["@output"])._targetClass())._instanceVariableNames())._sorted();
+instVars;
+size=_st(instVars)._size();
+size;
+_st(str).__lt_lt("initialize");
+$ctx2.sendIdx["<<"]=1;
+$3=_st(str)._cr();
+$ctx2.sendIdx["cr"]=1;
+$2=_st($3)._tab();
+$ctx2.sendIdx["tab"]=1;
+_st($2).__lt_lt("super initialize.");
+$ctx2.sendIdx["<<"]=2;
+$4=_st($2)._cr();
+$ctx2.sendIdx["cr"]=2;
+$4;
+$5=_st(str)._cr();
+$ctx2.sendIdx["cr"]=3;
+_st($5)._tab();
+$ctx2.sendIdx["tab"]=2;
+return _st(instVars)._withIndexDo_((function(name,index){
+return smalltalk.withContext(function($ctx3) {
+$6=_st(index).__tild_eq((1));
+$ctx3.sendIdx["~="]=1;
+if(smalltalk.assert($6)){
+_st(_st(str)._cr())._tab();
+};
+$7=_st(str).__lt_lt(name);
+$ctx3.sendIdx["<<"]=4;
+_st($7).__lt_lt(" := nil");
+$ctx3.sendIdx["<<"]=3;
+$8=_st(index).__tild_eq(size);
+if(smalltalk.assert($8)){
+return _st(str).__lt_lt(".");
+};
+}, function($ctx3) {$ctx3.fillBlock({name:name,index:index},$ctx2,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({str:str,instVars:instVars,size:size},$ctx1,1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"generateInitializeCodeForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "generateInitializeCodeForObject\x09\x0a\x09^ String streamContents: [ :str || instVars size |\x0a\x09\x09instVars := output targetClass instanceVariableNames sorted.\x0a\x09\x09size := instVars size.\x0a\x09\x09str << 'initialize'.\x0a\x09\x09str cr tab << 'super initialize.';cr.\x0a\x09\x09str cr tab.\x0a\x09\x09instVars withIndexDo: [ :name :index |\x0a\x09\x09\x09index ~= 1 ifTrue: [ str cr tab ].\x0a\x09\x09\x09str << name << ' := nil'.\x0a\x09\x09\x09index ~= size ifTrue: [ str << '.' ] ] ].",
+messageSends: ["streamContents:", "sorted", "instanceVariableNames", "targetClass", "size", "<<", "tab", "cr", "withIndexDo:", "ifTrue:", "~="],
+referencedClasses: ["String"]
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $HLGenerationOutputWithIndex(){return smalltalk.HLGenerationOutputWithIndex||(typeof HLGenerationOutputWithIndex=="undefined"?nil:HLGenerationOutputWithIndex)}
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.HLInitializeGenerator.superclass.fn.prototype._initialize.apply(_st(self), []);
+self["@output"]=_st($HLGenerationOutputWithIndex())._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09output := HLGenerationOutputWithIndex new",
+messageSends: ["initialize", "new"],
+referencedClasses: ["HLGenerationOutputWithIndex"]
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeCodeForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+function $HLMethodSourceCode(){return smalltalk.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_("initialize");
+_st($2)._sourceCode_(self._generateInitializeCodeForObject());
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"initializeCodeForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "initializeCodeForObject\x09\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector: 'initialize';\x0a\x09\x09sourceCode: self generateInitializeCodeForObject;\x0a\x09\x09yourself",
+messageSends: ["selector:", "new", "sourceCode:", "generateInitializeCodeForObject", "yourself"],
+referencedClasses: ["HLMethodSourceCode"]
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._addSourceCode_(self._initializeCodeForObject());
+return self}, function($ctx1) {$ctx1.fill(self,"initializeForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "initializeForObject\x0a\x09output addSourceCode: self initializeCodeForObject",
+messageSends: ["addSourceCode:", "initializeCodeForObject"],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeIndexForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._index_(self._computeIndexForObject());
+return self}, function($ctx1) {$ctx1.fill(self,"initializeIndexForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "initializeIndexForObject\x0a\x09output index: self computeIndexForObject",
+messageSends: ["index:", "computeIndexForObject"],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeProtocolForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._protocol_(self._retrieveProtocolForObject());
+return self}, function($ctx1) {$ctx1.fill(self,"initializeProtocolForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "initializeProtocolForObject\x0a\x09output protocol: self retrieveProtocolForObject",
+messageSends: ["protocol:", "retrieveProtocolForObject"],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "retrieveProtocolForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return "initialization";
+}, function($ctx1) {$ctx1.fill(self,"retrieveProtocolForObject",{},smalltalk.HLInitializeGenerator)})},
+args: [],
+source: "retrieveProtocolForObject\x0a\x09^ 'initialization'",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLInitializeGenerator);
+
+
+
+smalltalk.addClass('HLMethodSourceCode', smalltalk.Object, ['selector', 'sourceCode'], 'Helios-Helpers');
+smalltalk.HLMethodSourceCode.comment="I am a simple data object keeping track of the information about a method that will be compiled at the end of the generation process";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selector",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@selector"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selector",{},smalltalk.HLMethodSourceCode)})},
+args: [],
+source: "selector\x0a\x09^ selector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selector:",
+protocol: 'accessing',
+fn: function (aSelector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@selector"]=aSelector;
+return self}, function($ctx1) {$ctx1.fill(self,"selector:",{aSelector:aSelector},smalltalk.HLMethodSourceCode)})},
+args: ["aSelector"],
+source: "selector: aSelector\x0a\x09selector := aSelector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCode",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@sourceCode"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"sourceCode",{},smalltalk.HLMethodSourceCode)})},
+args: [],
+source: "sourceCode\x0a\x09^ sourceCode",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCode:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@sourceCode"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"sourceCode:",{aString:aString},smalltalk.HLMethodSourceCode)})},
+args: ["aString"],
+source: "sourceCode: aString\x0a\x09sourceCode := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLMethodSourceCode);
+
+
+});

+ 80 - 0
js/Kernel-Objects.js

@@ -1158,6 +1158,38 @@ referencedClasses: []
 smalltalk.Object);
 smalltalk.Object);
 
 
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorProtocolWith:",
+protocol: 'helios',
+fn: function (aGenerator){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aGenerator)._accessorProtocolForObject();
+return self}, function($ctx1) {$ctx1.fill(self,"accessorProtocolWith:",{aGenerator:aGenerator},smalltalk.Object.klass)})},
+args: ["aGenerator"],
+source: "accessorProtocolWith: aGenerator\x0a\x09aGenerator accessorProtocolForObject",
+messageSends: ["accessorProtocolForObject"],
+referencedClasses: []
+}),
+smalltalk.Object.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorsSourceCodesWith:",
+protocol: 'helios',
+fn: function (aGenerator){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aGenerator)._accessorsSourceCodesForObject();
+return self}, function($ctx1) {$ctx1.fill(self,"accessorsSourceCodesWith:",{aGenerator:aGenerator},smalltalk.Object.klass)})},
+args: ["aGenerator"],
+source: "accessorsSourceCodesWith: aGenerator\x0a\x09aGenerator accessorsSourceCodesForObject",
+messageSends: ["accessorsSourceCodesForObject"],
+referencedClasses: []
+}),
+smalltalk.Object.klass);
+
 smalltalk.addMethod(
 smalltalk.addMethod(
 smalltalk.method({
 smalltalk.method({
 selector: "heliosClass",
 selector: "heliosClass",
@@ -1189,6 +1221,54 @@ referencedClasses: []
 }),
 }),
 smalltalk.Object.klass);
 smalltalk.Object.klass);
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeIndexWith:",
+protocol: 'helios',
+fn: function (aGenerator){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aGenerator)._initializeIndexForObject();
+return self}, function($ctx1) {$ctx1.fill(self,"initializeIndexWith:",{aGenerator:aGenerator},smalltalk.Object.klass)})},
+args: ["aGenerator"],
+source: "initializeIndexWith: aGenerator\x0a\x09aGenerator initializeIndexForObject",
+messageSends: ["initializeIndexForObject"],
+referencedClasses: []
+}),
+smalltalk.Object.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeProtocolWith:",
+protocol: 'helios',
+fn: function (aGenerator){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aGenerator)._initializeProtocolForObject();
+return self}, function($ctx1) {$ctx1.fill(self,"initializeProtocolWith:",{aGenerator:aGenerator},smalltalk.Object.klass)})},
+args: ["aGenerator"],
+source: "initializeProtocolWith: aGenerator\x0a\x09aGenerator initializeProtocolForObject",
+messageSends: ["initializeProtocolForObject"],
+referencedClasses: []
+}),
+smalltalk.Object.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeSourceCodesWith:",
+protocol: 'helios',
+fn: function (aGenerator){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aGenerator)._initializeForObject();
+return self}, function($ctx1) {$ctx1.fill(self,"initializeSourceCodesWith:",{aGenerator:aGenerator},smalltalk.Object.klass)})},
+args: ["aGenerator"],
+source: "initializeSourceCodesWith: aGenerator\x0a\x09aGenerator initializeForObject",
+messageSends: ["initializeForObject"],
+referencedClasses: []
+}),
+smalltalk.Object.klass);
+
 
 
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.addClass('Boolean', smalltalk.Object, [], 'Kernel-Objects');
 smalltalk.Boolean.comment="I define the protocol for logic testing operations and conditional control structures for the logical values (see the `controlling` protocol).\x0a\x0aI have two instances, `true` and `false`.\x0a\x0aI am directly mapped to JavaScript Boolean. The `true` and `false` objects are the JavaScript boolean objects.\x0a\x0a## Usage Example:\x0a\x0a    aBoolean not ifTrue: [ ... ] ifFalse: [ ... ]";
 smalltalk.Boolean.comment="I define the protocol for logic testing operations and conditional control structures for the logical values (see the `controlling` protocol).\x0a\x0aI have two instances, `true` and `false`.\x0a\x0aI am directly mapped to JavaScript Boolean. The `true` and `false` objects are the JavaScript boolean objects.\x0a\x0a## Usage Example:\x0a\x0a    aBoolean not ifTrue: [ ... ] ifFalse: [ ... ]";

+ 82 - 0
st/Helios-Commands-Browser.st

@@ -155,6 +155,88 @@ label
 	^ 'Edit documentation'
 	^ 'Edit documentation'
 ! !
 ! !
 
 
+HLBrowserCommand subclass: #HLGenerateCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateCommand commentStamp!
+I am a group command used to gather all the commands generating code (`accessors`, `initialize`, etc)!
+
+!HLGenerateCommand class methodsFor: 'accessing'!
+
+key
+	^ 'h'
+!
+
+label
+	^ 'Generate'
+! !
+
+HLGenerateCommand subclass: #HLGenerateAccessorsCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateAccessorsCommand commentStamp!
+I am the command used to generate the `initialize` method depending of the selected class!
+
+!HLGenerateAccessorsCommand methodsFor: 'executing'!
+
+execute
+	| targetClass output first |
+	targetClass := self model selectedClass.
+
+	output := HLInitializeGenerator new
+		class: targetClass;
+		generate;
+		output.
+		
+	output serialize.
+	first := output sourceCodes first.
+	self model
+		selectedProtocol: output protocol;
+		selectedMethod:(targetClass>>first selector);
+		focusOnSourceCode
+! !
+
+!HLGenerateAccessorsCommand class methodsFor: 'accessing'!
+
+key
+	^ 'i'
+!
+
+label
+	^ 'Initialize'
+! !
+
+HLGenerateCommand subclass: #HLGenerateInitializeCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateInitializeCommand commentStamp!
+I am the command used to generate the `gettet` and the `setter` methods depending of the selected class!
+
+!HLGenerateInitializeCommand methodsFor: 'executing'!
+
+execute
+	| targetClass output |
+	targetClass := self model selectedClass.
+
+	output := HLAccessorsGenerator new
+		class: targetClass;
+		generate;
+		output.
+		
+	output serialize.
+	self model selectedProtocol: output protocol
+! !
+
+!HLGenerateInitializeCommand class methodsFor: 'accessing'!
+
+key
+	^ 'a'
+!
+
+label
+	^ 'Accessors'
+! !
+
 HLBrowserCommand subclass: #HLToggleCommand
 HLBrowserCommand subclass: #HLToggleCommand
 	instanceVariableNames: ''
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Browser'!
 	package: 'Helios-Commands-Browser'!

+ 270 - 0
st/Helios-Helpers.st

@@ -0,0 +1,270 @@
+Smalltalk current createPackage: 'Helios-Helpers'!
+Object subclass: #HLGenerationOutput
+	instanceVariableNames: 'sourceCodes protocol targetClass'
+	package: 'Helios-Helpers'!
+!HLGenerationOutput commentStamp!
+I am a simple data object used to store the result of a generation process!
+
+!HLGenerationOutput methodsFor: 'accessing'!
+
+protocol
+	^ protocol
+!
+
+protocol: aString
+	protocol := aString
+!
+
+sourceCodes
+	^ sourceCodes
+!
+
+sourceCodes: aCollection
+	sourceCodes := aCollection
+!
+
+targetClass
+	^ targetClass
+!
+
+targetClass: aClass
+	targetClass := aClass
+! !
+
+!HLGenerationOutput methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	sourceCodes := OrderedCollection new
+! !
+
+!HLGenerationOutput methodsFor: 'protocol'!
+
+addSourceCode: aString
+	sourceCodes add: aString
+!
+
+serialize
+	sourceCodes do: [ :methodSourceCode |
+		(targetClass includesSelector: methodSourceCode selector)
+			ifFalse: [ 
+				targetClass 
+					compile: methodSourceCode sourceCode
+					protocol: protocol ] ]
+! !
+
+HLGenerationOutput subclass: #HLGenerationOutputWithIndex
+	instanceVariableNames: 'index'
+	package: 'Helios-Helpers'!
+!HLGenerationOutputWithIndex commentStamp!
+I am a simple data object used to store the result of a generation process.
+
+In addition of my super class, I have an index where to put the cursor at the end of the process for the first method created (aka. the first in `sourceCodes`)!
+
+!HLGenerationOutputWithIndex methodsFor: 'accessing'!
+
+index
+	^ index
+!
+
+index: anIndex
+	index := anIndex
+! !
+
+Object subclass: #HLGenerator
+	instanceVariableNames: 'output'
+	package: 'Helios-Helpers'!
+!HLGenerator commentStamp!
+I am the abstract super class of the generators.
+
+My main method is `generate` which produce an `output` object!
+
+!HLGenerator methodsFor: 'accessing'!
+
+class: aClass
+	output targetClass: aClass
+!
+
+output
+	^ output
+! !
+
+!HLGenerator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	output := HLGenerationOutput new
+! !
+
+!HLGenerator methodsFor: 'protocol'!
+
+generate
+
+	output targetClass ifNil: [ self error: 'class should not be nil'].
+! !
+
+HLGenerator subclass: #HLAccessorsGenerator
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLAccessorsGenerator commentStamp!
+I am a generator used to compile the getters/setters of a class!
+
+!HLAccessorsGenerator methodsFor: 'double-dispatch'!
+
+accessorProtocolForObject
+	output protocol: 'accessing'
+!
+
+accessorsSourceCodesForObject
+	| sources |
+	
+	sources := OrderedCollection new.
+	output targetClass instanceVariableNames sorted do: [ :each | 
+		sources 
+			add: (self getterFor: each);
+			add: (self setterFor: each) ].
+	output sourceCodes: sources
+! !
+
+!HLAccessorsGenerator methodsFor: 'private'!
+
+getterFor: anInstanceVariable
+	^ HLMethodSourceCode new
+		selector:anInstanceVariable;
+		sourceCode: (String streamContents: [ :stream |
+		stream << anInstanceVariable.
+		stream cr cr tab.
+		stream << '^ ' << anInstanceVariable ])
+!
+
+setterFor: anInstanceVariable
+	^ HLMethodSourceCode new
+		selector: anInstanceVariable, ':';
+		sourceCode: (String streamContents: [ :stream |
+		stream << anInstanceVariable << ': anObject'.
+		stream cr cr tab.
+		stream << anInstanceVariable << ' := anObject' ])
+! !
+
+!HLAccessorsGenerator methodsFor: 'protocol'!
+
+generate
+	super generate.
+	
+	output targetClass 
+		accessorsSourceCodesWith: self;
+		accessorProtocolWith: self
+! !
+
+HLGenerator subclass: #HLInitializeGenerator
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLInitializeGenerator commentStamp!
+I am used to double-dispatch the `initialize` method(s) generation.
+
+Usage:
+
+    ^ HLInitializeGenerator new
+        class: aClass;
+        generate;
+        output
+
+I am a disposable object!
+
+!HLInitializeGenerator methodsFor: 'double-dispatch'!
+
+initializeForObject
+	output addSourceCode: self initializeCodeForObject
+!
+
+initializeIndexForObject
+	output index: self computeIndexForObject
+!
+
+initializeProtocolForObject
+	output protocol: self retrieveProtocolForObject
+! !
+
+!HLInitializeGenerator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	output := HLGenerationOutputWithIndex new
+! !
+
+!HLInitializeGenerator methodsFor: 'private'!
+
+computeIndexForObject
+	| instVars headerSize firstInstVarSize |
+	
+	"32 is the size of the `initiliaze super initialize` part"
+	headerSize := 32.
+	instVars := output targetClass instanceVariableNames.
+	firstInstVarSize := instVars sorted
+		ifEmpty: [ 0 ]
+		ifNotEmpty:[ instVars first size  + 4 ].
+	^ headerSize + firstInstVarSize
+!
+
+generateInitializeCodeForObject	
+	^ String streamContents: [ :str || instVars size |
+		instVars := output targetClass instanceVariableNames sorted.
+		size := instVars size.
+		str << 'initialize'.
+		str cr tab << 'super initialize.';cr.
+		str cr tab.
+		instVars withIndexDo: [ :name :index |
+			index ~= 1 ifTrue: [ str cr tab ].
+			str << name << ' := nil'.
+			index ~= size ifTrue: [ str << '.' ] ] ].
+!
+
+initializeCodeForObject	
+	^ HLMethodSourceCode new
+		selector: 'initialize';
+		sourceCode: self generateInitializeCodeForObject;
+		yourself
+!
+
+retrieveProtocolForObject
+	^ 'initialization'
+! !
+
+!HLInitializeGenerator methodsFor: 'protocol'!
+
+generate
+	super generate.
+	
+	output targetClass 
+		initializeSourceCodesWith: self;
+		initializeIndexWith: self;
+		initializeProtocolWith: self
+! !
+
+Object subclass: #HLMethodSourceCode
+	instanceVariableNames: 'selector sourceCode'
+	package: 'Helios-Helpers'!
+!HLMethodSourceCode commentStamp!
+I am a simple data object keeping track of the information about a method that will be compiled at the end of the generation process!
+
+!HLMethodSourceCode methodsFor: 'accessing'!
+
+selector
+	^ selector
+!
+
+selector: aSelector
+	selector := aSelector
+!
+
+sourceCode
+	^ sourceCode
+!
+
+sourceCode: aString
+	sourceCode := aString
+! !
+

+ 20 - 0
st/Kernel-Objects.st

@@ -389,11 +389,31 @@ respondsTo: aSelector
 
 
 !Object class methodsFor: 'helios'!
 !Object class methodsFor: 'helios'!
 
 
+accessorProtocolWith: aGenerator
+	aGenerator accessorProtocolForObject
+!
+
+accessorsSourceCodesWith: aGenerator
+	aGenerator accessorsSourceCodesForObject
+!
+
 heliosClass
 heliosClass
 	"Should be an Helios extension. Unfortunately, since helios can browse remote
 	"Should be an Helios extension. Unfortunately, since helios can browse remote
 	environments, we can't extend base classes"
 	environments, we can't extend base classes"
 	
 	
 	^ 'class'
 	^ 'class'
+!
+
+initializeIndexWith: aGenerator
+	aGenerator initializeIndexForObject
+!
+
+initializeProtocolWith: aGenerator
+	aGenerator initializeProtocolForObject
+!
+
+initializeSourceCodesWith: aGenerator
+	aGenerator initializeForObject
 ! !
 ! !
 
 
 !Object class methodsFor: 'initialization'!
 !Object class methodsFor: 'initialization'!

+ 1 - 0
support/helios.js

@@ -20,6 +20,7 @@ define([
 	'amber_core/Spaces',
 	'amber_core/Spaces',
 	'amber_core/Helios-Core',
 	'amber_core/Helios-Core',
 	'amber_core/Helios-Exceptions',
 	'amber_core/Helios-Exceptions',
+	'amber_core/Helios-Helpers',
 	'amber_core/Helios-Commands-Core',
 	'amber_core/Helios-Commands-Core',
 	'amber_core/Helios-Commands-Tools',
 	'amber_core/Helios-Commands-Tools',
 	'amber_core/Helios-Commands-Browser',
 	'amber_core/Helios-Commands-Browser',