Pragma: Preserving Identity and Adding #sourceNode
We improved Pragma a little in Pharo12.
Preserve Identity
Pragma will not be shalowCopied by AdditionalMethodState anymore when growing/shrinking.
This was a bit odd, but AdditionalMethodState was calling #shalowCopy on the pragmas (and Associations) that are contained in it when adding or removing a Pragma.
This was bad for many reasons:
- makes it hard to e.g. cache Pragmas by Identity (we had a bug due to that)
- lots of copies are created during creation of a CompiledMethod by the Compiler and later at runtime when adding or removing Method Properties
There are two PRs. The first was a patch to fix the bug that lead to Pragmas getting GCed in the Pragma Cache. The second is the real fix.
- 15074-Pragmas-lost-when-updating-methods #15087
- AdditionalMethodState: do not copy the Associations/Pragmas when growing or shrinking #15090
Create Pragma once during compilation
Make sure to create the Pragma once from the RBPragmaNode.
If you look at the senders of #asPragma, there used to be more than one. To make sure that Identity is preserved (and simplify things), we now create the Pragma once during name analysis. In OCASTSemanticAnalyzer>>#visitPragmaNode:, the Pragma instance is now created and added to the RBPragmaNode (there is now a pragma instance variable with a setter/getter).
visitPragmaNode: aPragmaNode
| varNode |
super visitPragmaNode: aPragmaNode.
aPragmaNode pragma: aPragmaNode asPragma.
aPragmaNode selector = #compilerOptions: ifTrue: [
aPragmaNode pragma sendTo:
self compilationContext ].
...
This means that we can now use it in OCASTTranslator >> visitPragmaNode: instead of calling #asPragma:
visitPragmaNode: aPragmaNode
| var |
aPragmaNode isParseError ifTrue: [ ^self ].
methodBuilder addPragma: aPragmaNode pragma.
...
This should make it easier to (in the future) experiment with the idea to use subclasses of Pragma.
Adding #sourceNode
We never added #sourceNode on Pragma.
For other code entities (like BlockClosure), we have a method #sourceNode that returns a pointer to the AST node that created the closure. With identity preserved, we can implement this. We leverage the idea that the order is the same of Pragmas on the CompiledMethod and RBPragmaNodes on the RBMethodNode:
sourceNode [
| index |
index := method pragmas identityIndexOf: self.
^ method ast pragmas at: index
see PR#15092
Improving the source view in the Inspector
When inspecting a Pragma, the default view shows the sourceCode of the method that this Pragma instance is in. But we could not highlight the pragma, as there was no connection between the Pragma instance and the RBPragmaNode instance of the AST that knows what to highlight in the text.
With #sourceNode implemented, we can improve the source view of the inspector (the default view). See NewTools PR#602
Posted on November 2, 2023 #Pharo #Pragma