Returning the source of a class as a string
I want to find the source of a Class and its methods (including all variables too, local , instance, class , class instance etc) and return them as a string or a collection of strings. I have found MethodNode>>sourceText and CompiledMethod>>sourceCode but I have no clue how to send these messages or if they are the messages I am looking for. Also any pointers as to how to navigate the Pharo syntax by code using something like AST would be greatly appreciated :) http://stackoverflow.com/questions/24961556/how-to-ask-an-object-to-return-i... Would it make more sense to use something like PettitParser ?
Le 25/07/2014 19:47, kilon alios a écrit :
I want to find the source of a Class and its methods (including all variables too, local , instance, class , class instance etc) and return them as a string or a collection of strings.
For the class, use aClass definition. For a method use CompiledMethod>>sourceCode; you can also ask the class for a selector as in: (aClass compiledMethodAt: self selector) sourceCode (works also if aClass is the meta side)
I have found MethodNode>>sourceText and CompiledMethod>>sourceCode but I have no clue how to send these messages or if they are the messages I am looking for.
Also any pointers as to how to navigate the Pharo syntax by code using something like AST would be greatly appreciated :)
http://stackoverflow.com/questions/24961556/how-to-ask-an-object-to-return-i...
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass. (you need the semantic analysis to have the variable bindings) To navigate the parse tree you either write a visitor or use existing search structures and extend nodes, as is done in SmartSuggestions. SmartSuggestions is probably an interesting place to look for that. The code above is from an ancestor to smart suggestion. Then I have some code which does a visit + rewrite over an AST tree (a code tracing tool). Refactoring also does that (all things RB).
Would it make more sense to use something like PettitParser ?
Maybe. But probably not, RBParser is good enough. Thierry
I don't understand how to use aClass definition from workspace nor I understand your selector message. (aClass compiledMethodAt: self selector) sourceCode , self would imply that i try to operate this from inside another class with self selector being the method itself at the time executed ? However because I try to parse pharo syntax to python code, the classes that I am parsing are unrelated to the parser class itself so I don't see how self selector would be relevant here. I also don't understand ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass what is aTarget ? Is there any documentation about RBParser how I can use it ? Or any documentation relevant to the subject ? On Fri, Jul 25, 2014 at 9:06 PM, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 19:47, kilon alios a écrit :
I want to find the source of a Class and its methods (including all variables too, local , instance, class , class instance etc) and return them as a string or a collection of strings.
For the class, use aClass definition. For a method use CompiledMethod>>sourceCode; you can also ask the class for a selector as in: (aClass compiledMethodAt: self selector) sourceCode
(works also if aClass is the meta side)
I have found MethodNode>>sourceText and CompiledMethod>>sourceCode but I have no clue how to send these messages or if they are the messages I am looking for.
Also any pointers as to how to navigate the Pharo syntax by code using something like AST would be greatly appreciated :)
http://stackoverflow.com/questions/24961556/how-to-ask- an-object-to-return-its-class-and-methods-source-as-a-string
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass.
(you need the semantic analysis to have the variable bindings)
To navigate the parse tree you either write a visitor or use existing search structures and extend nodes, as is done in SmartSuggestions.
SmartSuggestions is probably an interesting place to look for that. The code above is from an ancestor to smart suggestion.
Then I have some code which does a visit + rewrite over an AST tree (a code tracing tool). Refactoring also does that (all things RB).
Would it make more sense to use something like PettitParser ?
Maybe. But probably not, RBParser is good enough.
Thierry
Le 25/07/2014 20:37, kilon alios a écrit :
I don't understand how to use aClass definition from workspace nor I understand your selector message.
(aClass compiledMethodAt: self selector) sourceCode , self would imply that i try to operate this from inside another class with self selector being the method itself at the time executed ? No, just that you can write:
(Object compiledMethodAt: #printString) sourceCode That's me not sanitizing my code samples (lifting it from the AltBrowser)
However because I try to parse pharo syntax to python code, the classes that I am parsing are unrelated to the parser class itself so I don't see how self selector would be relevant here.
I also don't understand
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass
what is aTarget ?
Ok, as above, it should be understood as: ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
Is there any documentation about RBParser how I can use it ? Or any documentation relevant to the subject ?
Any documentation on compilers should do it. The RBParser is simply a parser, and it produces fairly simple ASTs (given that Smalltalk is simple). Thierry
On 25 Jul 2014, at 20:49, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 20:37, kilon alios a écrit :
I don't understand how to use aClass definition from workspace nor I understand your selector message.
(aClass compiledMethodAt: self selector) sourceCode , self would imply that i try to operate this from inside another class with self selector being the method itself at the time executed ? No, just that you can write:
(Object compiledMethodAt: #printString) sourceCode
That's me not sanitizing my code samples (lifting it from the AltBrowser)
However because I try to parse pharo syntax to python code, the classes that I am parsing are unrelated to the parser class itself so I don't see how self selector would be relevant here.
I also don't understand
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass
what is aTarget ?
Ok, as above, it should be understood as:
ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
There is a method on CompiledMethod called #ast that called the parser + semantic analysis: ( Object compiledMethodAt: #halt ) ast No need to know details about RBParser. Marcus
On 25 Jul 2014, at 20:55, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 20:49, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 20:37, kilon alios a écrit :
I don't understand how to use aClass definition from workspace nor I understand your selector message.
(aClass compiledMethodAt: self selector) sourceCode , self would imply that i try to operate this from inside another class with self selector being the method itself at the time executed ? No, just that you can write:
(Object compiledMethodAt: #printString) sourceCode
That's me not sanitizing my code samples (lifting it from the AltBrowser)
However because I try to parse pharo syntax to python code, the classes that I am parsing are unrelated to the parser class itself so I don't see how self selector would be relevant here.
I also don't understand
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass
what is aTarget ?
Ok, as above, it should be understood as:
ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
There is a method on CompiledMethod called #ast that called the parser + semantic analysis:
( Object compiledMethodAt: #halt ) ast
No need to know details about RBParser.
as example how to query the AST see the method #accessesSlot: accessesSlot: aSlot self ast nodesDo: [ :node | node isVariable and: [ node isInstance and: [ (node binding slot == aSlot) ifTrue: [^true]]]]. ^false
ok we are getting somewhere, the problem is that if I do (SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . Markus that beautiful nodesDo outputs the full syntax tree yeap definetly what I need to do what I want. Does the ast method applies also to classes or only compiled methods ? On Fri, Jul 25, 2014 at 9:59 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 20:55, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 20:49, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 20:37, kilon alios a écrit :
I don't understand how to use aClass definition from workspace nor I understand your selector message.
(aClass compiledMethodAt: self selector) sourceCode , self would imply that i try to operate this from inside another class with self selector being the method itself at the time executed ?
No, just that you can write:
(Object compiledMethodAt: #printString) sourceCode
That's me not sanitizing my code samples (lifting it from the AltBrowser)
However because I try to parse pharo syntax to python code, the classes that I am parsing are unrelated to the parser class itself so I don't see how self selector would be relevant here.
I also don't understand
ast := RBParser parseMethod: aTarget text asString onError: [ :msg :pos | ^ self ]. ast doSemanticAnalysisIn: self sourceClass
what is aTarget ?
Ok, as above, it should be understood as:
ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
There is a method on CompiledMethod called #ast that called the parser + semantic analysis:
( Object compiledMethodAt: #halt ) ast
No need to know details about RBParser.
as example how to query the AST see the method #accessesSlot:
accessesSlot: aSlot self ast nodesDo: [ :node | node isVariable and: [ node isInstance and: [ (node binding slot == aSlot) ifTrue: [^true]]]]. ^false
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Markus that beautiful nodesDo outputs the full syntax tree yeap definetly what I need to do what I want.
Does the ast method applies also to classes or only compiled methods ?
Only source code. A class definition is not entirely code (see above).
On Fri, Jul 25, 2014 at 9:59 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> wrote:
as example how to query the AST see the method #accessesSlot:
accessesSlot: aSlot self ast nodesDo: [ :node | node isVariable and: [ node isInstance and: [ (node binding slot == aSlot) ifTrue: [^true]]]]. ^false
Thanks Markus, this is a nice example. Thierry
Oh yes yes thank you, thank you both, this is exactly what I wanted. No need to send me your code ,I can parse this with regex I am already parsing pharo code with regex and it has been easy enough. It worked for messages like unary and keywords but I wanted to do more complex pharo syntax parsing to python. But if your code follows a better approach is more than welcomed. This is the first time I actually try to parse full syntax of a language. Basically what you gave me looks good enough to do what I want, I will also look at the classes themselves, I am surprised how small package AST is. I guess that the beauty of the smalltalk syntax. :) On Fri, Jul 25, 2014 at 10:51 PM, Thierry Goubier <thierry.goubier@gmail.com
wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables .
For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Markus that beautiful nodesDo outputs the full syntax tree yeap definetly what I need to do what I want.
Does the ast method applies also to classes or only compiled methods ?
Only source code. A class definition is not entirely code (see above).
On Fri, Jul 25, 2014 at 9:59 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
as example how to query the AST see the method #accessesSlot:
accessesSlot: aSlot self ast nodesDo: [ :node | node isVariable and: [ node isInstance and: [ (node binding slot == aSlot) ifTrue: [^true]]]]. ^false
Thanks Markus, this is a nice example.
Thierry
On 25 Jul 2014, at 21:59, kilon alios <kilon.alios@gmail.com> wrote:
Basically what you gave me looks good enough to do what I want, I will also look at the classes themselves, I am surprised how small package AST is. I guess that the beauty of the smalltalk syntax. :)
Yes, Smalltalk syntax is very simple compared to most other languages, see http://code.uko.tymchuk.me/2013/02/grammars-complexity-comparison.html
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too: https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Marcus
Le 25/07/2014 23:15, Marcus Denker a écrit :
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too:
https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Yes. What about the class definition format change described by Camillo?
Thierry
On 25 Jul 2014, at 23:28, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 23:15, Marcus Denker a écrit :
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too:
https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Yes. What about the class definition format change described by Camillo?
Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use {#ivar1. #ivar2 . #boolean => BooleanSlot } instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it. I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this: TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ Ah, and we need to think about âcategoryâ⦠as we now have packages. Marcus
On 25 Jul 2014, at 23:44, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 23:28, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 23:15, Marcus Denker a écrit :
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too:
https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Yes. What about the class definition format change described by Camillo?
Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ
Ah, and we need to think about âcategoryâ⦠as we now have packages.
But for the âwe need some kind of AST like structureâ it changes nothing: this is still a message send, but we need to reason about a class definition if we want to have suggestions (and with them e.g. BreakPoints on variables) working. Marcus
Le 25/07/2014 23:46, Marcus Denker a écrit :
On 25 Jul 2014, at 23:44, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 23:28, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 23:15, Marcus Denker a écrit :
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too:
https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Yes. What about the class definition format change described by Camillo? Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ I'd be tempted not to write an adhoc mini-language inside the instanceVariables array. Why not just something like:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . BooleanSlot named: #boolean } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ Maybe, with packages: TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . BooleanSlot named: #boolean } classVariables: {#MyGlobal} package: #'AST-Tests-Coreâ Not much more: we can allways drag and drop to the right place if needed, query if no package is given, cut and paste for keyboard use. If you want the grand show, I'll make you a wizard for creating classes with at least 10 steps ;)
Ah, and we need to think about âcategoryâ⦠as we now have packages.
But for the âwe need some kind of AST like structureâ it changes nothing: this is still a message send, but we need to reason about a class definition if we want to have suggestions (and with them e.g. BreakPoints on variables) working.
Marcus
I have that working without a real "ClassDefinition node" at the moment. Really very convenient to have the refactorings on instance variables working straight out of the class description text pane by just selecting the instance variable name in the string. Class definitions are either normal messages (for example in code creating a class by hand) or descriptions visible in browsers (interactive use). In the first case, you should not interpret them as class definitions since the class may/probably does not exist at that point. It is then just a message. In the second case, the GUI can ask for interpretation of the message into a class definition. I think this is how Gisela solution works, no? Thierry
On 26 Jul 2014, at 00:00, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 23:46, Marcus Denker a écrit :
On 25 Jul 2014, at 23:44, Marcus Denker <marcus.denker@inria.fr> wrote:
On 25 Jul 2014, at 23:28, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 23:15, Marcus Denker a écrit :
On 25 Jul 2014, at 21:51, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 21:42, kilon alios a écrit :
ok we are getting somewhere, the problem is that if I do
(SomeClass compiledMethodAt: #nameOfMethod it will look only in the instance side for method, how I look also for class methods ? Also how I can return source of class ? to be specific I need the names of instance variables, class variables and class instance variables . For the class method:
SomeClass class compiledMethodAt: #nameOfClassMethod
For the instance variable, etc... SomeClass definition will give you that. But it's a bit tricky to parse; for example, if you want a reification (instance variable name is recognized as instance variable name in the ast), I have some code which does: parse, rewrite and reparse on a class definition (for the smart suggestion thing).
Yes, we need that⦠there is code on the issue tracker, too:
https://pharo.fogbugz.com/f/cases/10983/Represent-a-class-definition-with-AS... Yes. What about the class definition format change described by Camillo? Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ I'd be tempted not to write an adhoc mini-language inside the instanceVariables array. Why not just something like:
What I like with the #name=>Var notation is that it puts the name of the variable first. And it is just an expression (you can evaluate it, itâs the same as BooleanSlot named: #boolean) So it is just an expession, and e.g. classes could create slots: {Integer typedSlotNamed: #i}
If you want the grand show, I'll make you a wizard for creating classes with at least 10 steps ;)
Ah, and we need to think about âcategoryâ⦠as we now have packages.
But for the âwe need some kind of AST like structureâ it changes nothing: this is still a message send, but we need to reason about a class definition if we want to have suggestions (and with them e.g. BreakPoints on variables) working.
Marcus
I have that working without a real "ClassDefinition node" at the moment. Really very convenient to have the refactorings on instance variables working straight out of the class description text pane by just selecting the instance variable name in the string.
Class definitions are either normal messages (for example in code creating a class by hand) or descriptions visible in browsers (interactive use).
In the first case, you should not interpret them as class definitions since the class may/probably does not exist at that point. It is then just a message.
In the second case, the GUI can ask for interpretation of the message into a class definition. I think this is how Gisela solution works, no?
Yes! Marcus
Le 26/07/2014 10:00, stepharo a écrit :
What I like with the #name=>Var notation is that it puts the name of the variable first. And it is just an expression (you can evaluate it, itâs the same as BooleanSlot named: #boolean)
yes this is nice.
Not much by me. Have to remember what => means (and that it isn't -> or
= or > or + or @)
I'd prefer self-documenting and explicit: #name isA: ClassOfSlot (4 characters instead of 2, ok, but not difficult to remember) or the Roassal approach: single character, which does not try too much to have a meaning, but be easy to memorize. #name @ ClassOfSlot (wouldn't that mess with points?) After, I'd say #name first if it is proven that we think "name of instance variable" before "type of slot" when we write a class description (is also better when looking at "name of instance variable" with optional qualification). Thierry
Thierry we asked Mark Rizun to look into get a full "compilation unit" as an AST: - AST for packages - AST for class definition. He should look at what gisela proposed and any feedback is interesting. Stef
On 26 Jul 2014, at 10:02, stepharo <stepharo@free.fr> wrote:
Thierry we asked Mark Rizun to look into get a full "compilation unit" as an AST: - AST for packages - AST for class definition. He should look at what gisela proposed and any feedback is interesting.
Only the name AST is wrong: the S stand for Syntax. There is no syntax for Classes, nor packages. What we want is models for everything with *the same API* as the nodes of the AST. (and visitors that can visit the whole structure) Marcus
Le 26/07/2014 10:04, Marcus Denker a écrit :
On 26 Jul 2014, at 10:02, stepharo <stepharo@free.fr> wrote:
Thierry we asked Mark Rizun to look into get a full "compilation unit" as an AST: - AST for packages - AST for class definition. He should look at what gisela proposed and any feedback is interesting.
Only the name AST is wrong: the S stand for Syntax. There is no syntax for Classes, nor packages. We could have one. It would allow people to write Pharo code with emacs, have a pharo emacs-el mode, and try a different way to use git :)
What we want is models for everything with *the same API* as the nodes of the AST. (and visitors that can visit the whole structure) This would be cool. I have the nodes and the visitors for all the way from packages to method, but it stops at the method / class description level (and switches to the RB ast then).
Thierry
there Shampoo already http://dmitrymatveev.co.uk/shampoo/ or do you mean something different ? On Sat, Jul 26, 2014 at 1:04 PM, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 26/07/2014 10:04, Marcus Denker a écrit :
On 26 Jul 2014, at 10:02, stepharo <stepharo@free.fr> wrote:
Thierry we asked Mark Rizun to look into get a full "compilation unit"
as an AST: - AST for packages - AST for class definition. He should look at what gisela proposed and any feedback is interesting.
Only the name AST is wrong: the S stand for Syntax. There is no syntax for Classes, nor packages.
We could have one. It would allow people to write Pharo code with emacs, have a pharo emacs-el mode, and try a different way to use git :)
What we want is models for everything with *the same API* as the nodes of the AST. (and visitors that can visit the whole structure)
This would be cool. I have the nodes and the visitors for all the way from packages to method, but it stops at the method / class description level (and switches to the RB ast then).
Thierry
Le 26/07/2014 12:12, kilon alios a écrit :
there Shampoo already
http://dmitrymatveev.co.uk/shampoo/ Didn't know about that one. Looks good :)
or do you mean something different ? Yes. A true, single source approach. Smalltalk as 10 000 - 100 000 lines of code in a single file. People recompiling a complete package each time they change a method.
The real programming world, good to sell to companies :) We also need to look into making Smalltalk less efficient at code reuse. It's possible to write far too effective code in very few lines. Like that we would be able to increase our GitHub presence. Thierry
On Sat, Jul 26, 2014 at 1:04 PM, Thierry Goubier <thierry.goubier@gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
Le 26/07/2014 10:04, Marcus Denker a écrit :
On 26 Jul 2014, at 10:02, stepharo <stepharo@free.fr <mailto:stepharo@free.fr>> wrote:
Thierry we asked Mark Rizun to look into get a full "compilation unit" as an AST: - AST for packages - AST for class definition. He should look at what gisela proposed and any feedback is interesting.
Only the name AST is wrong: the S stand for Syntax. There is no syntax for Classes, nor packages.
We could have one. It would allow people to write Pharo code with emacs, have a pharo emacs-el mode, and try a different way to use git :)
What we want is models for everything with *the same API* as the nodes of the AST. (and visitors that can visit the whole structure)
This would be cool. I have the nodes and the visitors for all the way from packages to method, but it stops at the method / class description level (and switches to the RB ast then).
Thierry
Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ
Ah, and we need to think about âcategoryâ⦠as we now have packages.
You see how this is great not to have PoolDict in our face :) I would rename classVariables: into sharedVariables: and make them optional :)
On 26 Jul 2014, at 09:58, stepharo <stepharo@free.fr> wrote:
Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ
Ah, and we need to think about âcategoryâ⦠as we now have packages.
You see how this is great not to have PoolDict in our face :) I would rename classVariables: into sharedVariables: and make them optional :)
I actually think shared variables is not good⦠everyone talks about Class Variables All Tutorials, all books. And it is very easy to confuse the term with Pools (I actually did so when looking at the Class Builder). Marcus
On 26 Jul 2014, at 10:03, Marcus Denker <marcus.denker@inria.fr> wrote:
On 26 Jul 2014, at 09:58, stepharo <stepharo@free.fr> wrote:
Slowly working on it⦠very early (and right now broken) stage is in the image. And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ
Ah, and we need to think about âcategoryâ⦠as we now have packages.
You see how this is great not to have PoolDict in our face :) I would rename classVariables: into sharedVariables: and make them optional :)
I actually think shared variables is not good⦠everyone talks about Class Variables All Tutorials, all books. And it is very easy to confuse the term with Pools (I actually did so when looking at the Class Builder).
e.g. we would need to change the whole api⦠now we have aClass classVariableNamed: âMyClassVarâ. would need to change to aClass sharedVariableNamed: âMyClassVarâ. and then: arenât Pool imported variables shared? So would this return a variable from a pool? if not, wouldnât that be confusing? Marcus
I don't understand what "shared" means here . Are we talking about slots ? It looks to me very vague as a name . On Sat, Jul 26, 2014 at 11:08 AM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 26 Jul 2014, at 10:03, Marcus Denker <marcus.denker@inria.fr> wrote:
On 26 Jul 2014, at 09:58, stepharo <stepharo@free.fr> wrote:
Slowly working on it⦠very early (and right now broken) stage is in
the image.
And it is not yet decided how it will look like exactly⦠the only thing clear is that we need to use
{#ivar1. #ivar2 . #boolean => BooleanSlot }
instead of the strings⦠both for ivars and class vars⦠I want to finish and debug the machinery around and then start to play with it.
I am a bit tempted to go the âbackward compatibleâ way and not use the term Slot but something like this:
TestCase subclass: #RBProgramNodeTest instanceVariables :{#ivar1. #ivar2 . #boolean => BooleanSlot } classVariables: {#MyGlobal} category: 'AST-Tests-Coreâ
Ah, and we need to think about âcategoryâ⦠as we now have packages.
You see how this is great not to have PoolDict in our face :) I would rename classVariables: into sharedVariables: and make them optional :)
I actually think shared variables is not good⦠everyone talks about Class Variables All Tutorials, all books. And it is very easy to confuse the term with Pools (I actually did so when looking at the Class Builder).
e.g. we would need to change the whole api⦠now we have
aClass classVariableNamed: âMyClassVarâ.
would need to change to
aClass sharedVariableNamed: âMyClassVarâ.
and then: arenât Pool imported variables shared? So would this return a variable from a pool? if not, wouldnât that be confusing?
Marcus
Le 25/07/2014 20:55, Marcus Denker a écrit :
On 25 Jul 2014, at 20:49, Thierry Goubier <thierry.goubier@gmail.com <mailto:thierry.goubier@gmail.com>> wrote:
Ok, as above, it should be understood as:
ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
There is a method on CompiledMethod called #ast that called the parser + semantic analysis:
( Object compiledMethodAt: #halt ) ast
No need to know details about RBParser. Marcus
Cool. Thanks. But when you start to use the ast, you'd better have a look into the RBParser / RBAST stuff, no? Thierry
On 25 Jul 2014, at 21:52, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Le 25/07/2014 20:55, Marcus Denker a écrit :
On 25 Jul 2014, at 20:49, Thierry Goubier <thierry.goubier@gmail.com> wrote:
Ok, as above, it should be understood as:
ast := RBParser parseMethod: (Object compiledMethodAt: #printString) onError: [ :msg :ps | ]. ast doSemanticAnalysisIn: self sourceClass.
There is a method on CompiledMethod called #ast that called the parser + semantic analysis:
( Object compiledMethodAt: #halt ) ast
No need to know details about RBParser.
Marcus
Cool. Thanks.
But when you start to use the ast, you'd better have a look into the RBParser / RBAST stuff, no?
yes! Marcus
participants (4)
-
kilon alios -
Marcus Denker -
stepharo -
Thierry Goubier