From a0748df231bada1aa744c7535dfa7128d266daf7 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 3 Apr 2024 17:03:51 -0300 Subject: [PATCH 1/6] Add extensions and tooling to support transient, invariant and non-persistent GS64 options in Tonel --- .../Namespace.extension.st | 8 ++--- .../TonelWriterV3.extension.st | 26 +++++++++++++++ source/Buoy-Development-Tools/package.st | 2 +- .../Behavior.extension.st | 33 +++++++++++++++++-- .../OSPlatform.extension.st | 8 ++--- .../PharoPlatform.class.st | 19 ++++++----- .../Symbol.extension.st | 4 +-- .../package.st | 2 +- 8 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 source/Buoy-Development-Tools/TonelWriterV3.extension.st diff --git a/source/Buoy-Development-Tools/Namespace.extension.st b/source/Buoy-Development-Tools/Namespace.extension.st index 848abe5..d9f4844 100644 --- a/source/Buoy-Development-Tools/Namespace.extension.st +++ b/source/Buoy-Development-Tools/Namespace.extension.st @@ -1,20 +1,20 @@ -Extension { #name : #Namespace } +Extension { #name : 'Namespace' } -{ #category : #'*Buoy-Development-Tools' } +{ #category : '*Buoy-Development-Tools' } Namespace >> gtInspectorItemsIn: composite [ ^ bindings gtInspectorItemsIn: composite ] -{ #category : #'*Buoy-Development-Tools' } +{ #category : '*Buoy-Development-Tools' } Namespace >> inspectionItems: builder [ ^ bindings inspectionItems: builder ] -{ #category : #'*Buoy-Development-Tools' } +{ #category : '*Buoy-Development-Tools' } Namespace >> spotterForKeysFor: aStep [ diff --git a/source/Buoy-Development-Tools/TonelWriterV3.extension.st b/source/Buoy-Development-Tools/TonelWriterV3.extension.st new file mode 100644 index 0000000..7ffdee7 --- /dev/null +++ b/source/Buoy-Development-Tools/TonelWriterV3.extension.st @@ -0,0 +1,26 @@ +Extension { #name : 'TonelWriterV3' } + +{ #category : '*Buoy-Development-Tools' } +TonelWriterV3 >> typeClassDefinitionOf: aClassDefinition [ + + | definition | + definition := OrderedDictionary new. + self + at: #name put: aClassDefinition className in: definition; + at: #superclass put: aClassDefinition superclassName in: definition. + aClassDefinition type = #normal ifFalse: [ self at: #type put: aClassDefinition type in: definition ]. + aClassDefinition hasTraitComposition ifTrue: [ definition at: #traits put: aClassDefinition traitCompositionString ]. + aClassDefinition hasClassTraitComposition ifTrue: [ definition at: #classTraits put: aClassDefinition classTraitCompositionString ]. + aClassDefinition instVarNames ifNotEmpty: [ :vars | definition at: #instVars put: vars asArray ]. + (aClassDefinition variables + select: #isClassVariable + thenCollect: #name) ifNotEmpty: [ :vars | definition at: #classVars put: vars asArray ]. + (aClassDefinition variables + select: #isPoolImport + thenCollect: #name) ifNotEmpty: [ :vars | definition at: #pools put: vars asArray ]. + aClassDefinition classInstVarNames ifNotEmpty: [ :vars | definition at: #classInstVars put: vars asArray ]. + self setPackageInfoOf: aClassDefinition in: definition. + "Write gs_options if available as class properties" + (aClassDefinition actualClass propertyAt: #gs_options) ifNotNil: [ :options | definition at: #gs_options put: options ]. + ^ self toSTON: definition +] diff --git a/source/Buoy-Development-Tools/package.st b/source/Buoy-Development-Tools/package.st index 3b91d60..e102431 100644 --- a/source/Buoy-Development-Tools/package.st +++ b/source/Buoy-Development-Tools/package.st @@ -1 +1 @@ -Package { #name : #'Buoy-Development-Tools' } +Package { #name : 'Buoy-Development-Tools' } diff --git a/source/Buoy-Metaprogramming-Pharo-Extensions/Behavior.extension.st b/source/Buoy-Metaprogramming-Pharo-Extensions/Behavior.extension.st index 8c88cc1..5938ba5 100644 --- a/source/Buoy-Metaprogramming-Pharo-Extensions/Behavior.extension.st +++ b/source/Buoy-Metaprogramming-Pharo-Extensions/Behavior.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #Behavior } +Extension { #name : 'Behavior' } -{ #category : #'*Buoy-Metaprogramming-Pharo-Extensions' } +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } Behavior >> allLeafSubclasses [ | leafs | @@ -9,3 +9,32 @@ Behavior >> allLeafSubclasses [ self allSubclassesDo: [ :class | class subclasses ifEmpty: [ leafs add: class ] ]. ^ leafs ] + +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } +Behavior >> makeInstancesDbTransient [ + "In GS64 instances of classes that are DbTransient can be committed — that is, there is no error if they are committed — + but their instance variables are not written to disk. + + These properties are written later by our version of the TonelWriterV3" + + self propertyAt: #gs_options put: #( 'dbTransient' ) +] + +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } +Behavior >> makeInstancesInvariant [ + "In GS64 instances of this class will be made invariant as soon as they are committed. + + These properties are written later by our version of the TonelWriterV3" + + self propertyAt: #gs_options put: #( 'instancesInvariant' ) +] + +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } +Behavior >> makeInstancesNonPersistent [ + "In GS64 instances of this class cannot be committed, so you cannot include references to + instances of non-persistent classes within a persistent data structure. + + These properties are written later by our version of the TonelWriterV3" + + self propertyAt: #gs_options put: #( 'instancesNonPersistent' ) +] diff --git a/source/Buoy-Metaprogramming-Pharo-Extensions/OSPlatform.extension.st b/source/Buoy-Metaprogramming-Pharo-Extensions/OSPlatform.extension.st index f9102b0..573da1b 100644 --- a/source/Buoy-Metaprogramming-Pharo-Extensions/OSPlatform.extension.st +++ b/source/Buoy-Metaprogramming-Pharo-Extensions/OSPlatform.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #OSPlatform } +Extension { #name : 'OSPlatform' } -{ #category : #'*Buoy-Metaprogramming-Pharo-Extensions' } +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } OSPlatform >> environmentAt: aVariableName ifPresent: aBlock ifAbsent: anAbsentBlock [ ^ self environment @@ -9,13 +9,13 @@ OSPlatform >> environmentAt: aVariableName ifPresent: aBlock ifAbsent: anAbsentB ifAbsent: anAbsentBlock ] -{ #category : #'*Buoy-Metaprogramming-Pharo-Extensions' } +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } OSPlatform >> environmentAt: variableName put: value [ self environment at: variableName put: value ] -{ #category : #'*Buoy-Metaprogramming-Pharo-Extensions' } +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } OSPlatform >> removeEnvironmentKey: variableName [ self environment removeKey: variableName diff --git a/source/Buoy-Metaprogramming-Pharo-Extensions/PharoPlatform.class.st b/source/Buoy-Metaprogramming-Pharo-Extensions/PharoPlatform.class.st index d48bf10..aeb4b0f 100644 --- a/source/Buoy-Metaprogramming-Pharo-Extensions/PharoPlatform.class.st +++ b/source/Buoy-Metaprogramming-Pharo-Extensions/PharoPlatform.class.st @@ -1,41 +1,42 @@ Class { - #name : #PharoPlatform, - #superclass : #LanguagePlatform, - #category : #'Buoy-Metaprogramming-Pharo-Extensions' + #name : 'PharoPlatform', + #superclass : 'LanguagePlatform', + #category : 'Buoy-Metaprogramming-Pharo-Extensions', + #package : 'Buoy-Metaprogramming-Pharo-Extensions' } -{ #category : #'class initialization' } +{ #category : 'class initialization' } PharoPlatform class >> initialize [ LanguagePlatform setCurrentTo: self new ] -{ #category : #reflection } +{ #category : 'reflection' } PharoPlatform >> atInstanceVariableNamed: name on: object put: value [ object instVarNamed: name put: value ] -{ #category : #'process scheduling' } +{ #category : 'process scheduling' } PharoPlatform >> fork: block named: processName at: priority [ ^ block forkAt: priority named: processName ] -{ #category : #reflection } +{ #category : 'reflection' } PharoPlatform >> globalNamed: aSymbol ifAbsent: absentBlock [ ^ Smalltalk globals at: aSymbol ifAbsent: absentBlock ] -{ #category : #reflection } +{ #category : 'reflection' } PharoPlatform >> includesGlobalNamed: aSymbol [ ^ Smalltalk globals includesKey: aSymbol ] -{ #category : #accessing } +{ #category : 'accessing' } PharoPlatform >> os [ ^ OSPlatform current diff --git a/source/Buoy-Metaprogramming-Pharo-Extensions/Symbol.extension.st b/source/Buoy-Metaprogramming-Pharo-Extensions/Symbol.extension.st index 1fbba8b..e652fd1 100644 --- a/source/Buoy-Metaprogramming-Pharo-Extensions/Symbol.extension.st +++ b/source/Buoy-Metaprogramming-Pharo-Extensions/Symbol.extension.st @@ -1,6 +1,6 @@ -Extension { #name : #Symbol } +Extension { #name : 'Symbol' } -{ #category : #'*Buoy-Metaprogramming-Pharo-Extensions' } +{ #category : '*Buoy-Metaprogramming-Pharo-Extensions' } Symbol >> argumentCount [ ^self numArgs diff --git a/source/Buoy-Metaprogramming-Pharo-Extensions/package.st b/source/Buoy-Metaprogramming-Pharo-Extensions/package.st index 6d81509..cf6efbf 100644 --- a/source/Buoy-Metaprogramming-Pharo-Extensions/package.st +++ b/source/Buoy-Metaprogramming-Pharo-Extensions/package.st @@ -1 +1 @@ -Package { #name : #'Buoy-Metaprogramming-Pharo-Extensions' } +Package { #name : 'Buoy-Metaprogramming-Pharo-Extensions' } From 148d1d3245cc65e2f499486a0739dfa63cdbd4a6 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 3 Apr 2024 17:13:04 -0300 Subject: [PATCH 2/6] Add how to --- docs/how-to/how-to-support-gs64-options.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/how-to/how-to-support-gs64-options.md diff --git a/docs/how-to/how-to-support-gs64-options.md b/docs/how-to/how-to-support-gs64-options.md new file mode 100644 index 0000000..bb872fa --- /dev/null +++ b/docs/how-to/how-to-support-gs64-options.md @@ -0,0 +1,17 @@ +# How to support GS64 class options + +GemStone/S 64 includes some options during class creation that change the +behavior of the instances. + +There's support in Rowan to specify these options using the Tonel format +by filling the `gs_options` metadata in the class creation section. However, +by default Pharo will remove this metadata when committing code losing the +options. To avoid this behavior and retain the options, load the `Tool` group +and send in the class `initialize` message one of the following messages: + +- `makeInstancesDbTransient` +- `makeInstancesInvariant` +- `makeInstancesNonPersistent` + +This will configure the options as class properties in Pharo, and later the +Tonel Writer will use these options for the metadata. From 82e360495aa84504faa9c4a5d7de20cf384684d0 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 3 Apr 2024 17:27:14 -0300 Subject: [PATCH 3/6] Add inspector extensions to see gs_options --- .../Behavior.extension.st | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 source/Buoy-Development-Tools/Behavior.extension.st diff --git a/source/Buoy-Development-Tools/Behavior.extension.st b/source/Buoy-Development-Tools/Behavior.extension.st new file mode 100644 index 0000000..8c37410 --- /dev/null +++ b/source/Buoy-Development-Tools/Behavior.extension.st @@ -0,0 +1,20 @@ +Extension { #name : 'Behavior' } + +{ #category : '*Buoy-Development-Tools' } +Behavior >> inspectionGs64Options: builder [ + + + ^ builder newTable + addColumn: + (SpStringTableColumn + title: 'Option' + evaluated: [ :option | option ]); + items: (self propertyAt: #gs_options); + yourself +] + +{ #category : '*Buoy-Development-Tools' } +Behavior >> inspectionGs64OptionsContext: aContext [ + + aContext active: (self hasProperty: #gs_options) +] From 726ace4d38f56050d5a9628b2f883e8e67f9aee5 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 3 Apr 2024 18:09:58 -0300 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Maximiliano Tabacman --- docs/how-to/how-to-support-gs64-options.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/how-to/how-to-support-gs64-options.md b/docs/how-to/how-to-support-gs64-options.md index bb872fa..014189f 100644 --- a/docs/how-to/how-to-support-gs64-options.md +++ b/docs/how-to/how-to-support-gs64-options.md @@ -1,11 +1,11 @@ # How to support GS64 class options GemStone/S 64 includes some options during class creation that change the -behavior of the instances. +behavior of instances of that class. -There's support in Rowan to specify these options using the Tonel format +Rowan has support to specify these options using the Tonel format by filling the `gs_options` metadata in the class creation section. However, -by default Pharo will remove this metadata when committing code losing the +Pharo will be default remove this metadata when committing code, which loses these options. To avoid this behavior and retain the options, load the `Tool` group and send in the class `initialize` message one of the following messages: @@ -13,5 +13,5 @@ and send in the class `initialize` message one of the following messages: - `makeInstancesInvariant` - `makeInstancesNonPersistent` -This will configure the options as class properties in Pharo, and later the -Tonel Writer will use these options for the metadata. +This will configure the options as class properties in Pharo, which will then be used by the +Tonel Writer to set these options to the metadata. From 43a95e0f9454c830d8ba633cd656f467b594f307 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Thu, 4 Apr 2024 08:16:01 -0300 Subject: [PATCH 5/6] Fix formatting --- source/Buoy-Development-Tools/Behavior.extension.st | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/Buoy-Development-Tools/Behavior.extension.st b/source/Buoy-Development-Tools/Behavior.extension.st index 8c37410..7c9e77e 100644 --- a/source/Buoy-Development-Tools/Behavior.extension.st +++ b/source/Buoy-Development-Tools/Behavior.extension.st @@ -5,16 +5,13 @@ Behavior >> inspectionGs64Options: builder [ ^ builder newTable - addColumn: - (SpStringTableColumn - title: 'Option' - evaluated: [ :option | option ]); - items: (self propertyAt: #gs_options); + addColumn: ( SpStringTableColumn title: 'Option' evaluated: [ :option | option ] ); + items: ( self propertyAt: #gs_options ); yourself ] { #category : '*Buoy-Development-Tools' } Behavior >> inspectionGs64OptionsContext: aContext [ - aContext active: (self hasProperty: #gs_options) + aContext active: ( self hasProperty: #gs_options ) ] From 9230fe9af9603d75d74e32d06b50b50237cc9474 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Thu, 4 Apr 2024 08:17:58 -0300 Subject: [PATCH 6/6] Fix markdown lint --- docs/how-to/how-to-support-gs64-options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/how-to/how-to-support-gs64-options.md b/docs/how-to/how-to-support-gs64-options.md index 014189f..a8150d5 100644 --- a/docs/how-to/how-to-support-gs64-options.md +++ b/docs/how-to/how-to-support-gs64-options.md @@ -13,5 +13,5 @@ and send in the class `initialize` message one of the following messages: - `makeInstancesInvariant` - `makeInstancesNonPersistent` -This will configure the options as class properties in Pharo, which will then be used by the -Tonel Writer to set these options to the metadata. +This will configure the options as class properties in Pharo, which will then be +used by the Tonel Writer to set these options to the metadata.