Last week we merged some improvements related to Pragma in Pharo12
This was a bit odd, but AdditionalMethodState was calling #shalowCopy on the pragmas (and Associations) that are contained in it.
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 and usage of Method Properties
see the two PRs:
- 15074-Pragmas-lost-when-updating-methods #15087 https://github.com/pharo-project/pharo/pull/15087 - AdditionalMethodState: do not copy the Associations/Pragmas when growing or shrinking #15090 https://github.com/pharo-project/pharo/pull/15090
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 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.
We never added #sourceNode on Pragma... now we have it. This uses the idea that the order is the same of Pragmas on the CompiledMethod and RBPragmaNodes on the RBMethodNode:
| index |
index := method pragmas identityIndexOf: self.
^ method ast pragmas at: index
see PR #15092 for both 2 and 3: https://github.com/pharo-project/pharo/pull/15092