Pragma Improvements: Identity, sourceNode and Inspector

MD
Marcus Denker
Mon, Oct 30, 2023 3:54 PM

Last week we merged some improvements related to Pragma in Pharo12

  1. 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.

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
  1. 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 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.

  1. add #sourceNode

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:

sourceNode [
| 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

  1. with #sourceNode implemented, we can improve the source view of the inspector (the default view). See PR https://github.com/pharo-spec/NewTools/pull/602
Last week we merged some improvements related to Pragma in Pharo12 1) 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. 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 2) 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 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. 3) add #sourceNode 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: sourceNode [ | 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 4) with #sourceNode implemented, we can improve the source view of the inspector (the default view). See PR https://github.com/pharo-spec/NewTools/pull/602