Skip to content

Commit

Permalink
Update the way to declare a metaclass class and fix some bugs in the …
Browse files Browse the repository at this point in the history
…metaclass class selected
  • Loading branch information
jecisc committed May 30, 2024
1 parent 7e65c53 commit 06d4052
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 41 deletions.
11 changes: 4 additions & 7 deletions src/Shift-ClassBuilder/ShDefaultBuilderEnhancer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ ShDefaultBuilderEnhancer >> initializeBuilder: aBuilder [
aBuilder addChangeComparer: ShMetaclassChangeDetector
]

{ #category : 'events' }
ShDefaultBuilderEnhancer >> metaclassCreated: builder [
{ #category : 'accessing' }
ShDefaultBuilderEnhancer >> metaclassClassFor: aBuilder [

^ Metaclass
]

{ #category : 'events' }
Expand All @@ -98,11 +100,6 @@ ShDefaultBuilderEnhancer >> migrateToClass: aClass installer: aShiftClassInstall
aShiftClassInstaller migrateClassTo: aClass
]

{ #category : 'class modifications' }
ShDefaultBuilderEnhancer >> newMetaclass: builder [
^ builder metaclassClass new
]

{ #category : 'class modifications' }
ShDefaultBuilderEnhancer >> on: newClass declareClassVariables: sharedVariables sharing: sharedPoolNames [
newClass
Expand Down
17 changes: 5 additions & 12 deletions src/Shift-ClassBuilder/ShiftClassBuilder.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,13 @@ ShiftClassBuilder >> createClass [
{ #category : 'building' }
ShiftClassBuilder >> createMetaclass [

newMetaclass := self builderEnhancer newMetaclass: self.
newMetaclass := self metaclassClass new.

self builderEnhancer
configureMetaclass: newMetaclass
superclass: self metaSuperclass
withLayoutType: FixedLayout
slots: (self withAdditionalSlots: self classSlots).

self builderEnhancer metaclassCreated: self
slots: (self withAdditionalSlots: self classSlots)
]

{ #category : 'building' }
Expand Down Expand Up @@ -317,9 +315,7 @@ ShiftClassBuilder >> fillClassSideFromEnvironment: anEnvironment [
| old |
old := anEnvironment at: name ifAbsent: [ ^ self ].

self metaclassClass: old class class.
self classSlots: old class slots.
self classTraits: old class traitComposition
self classSlots: old class slots
]

{ #category : 'initialization' }
Expand Down Expand Up @@ -482,12 +478,9 @@ ShiftClassBuilder >> metaSuperclass: aClass [

{ #category : 'accessing' }
ShiftClassBuilder >> metaclassClass [
^ metaclassClass ifNil: [ Metaclass ]
]
"The metaclass class is determined by the builder enhancer. In case you want to play with your own metaclass class, you can implement a subclass of the buildre enhancer and use this one overriding the method #metaclassClassFor:."

{ #category : 'accessing' }
ShiftClassBuilder >> metaclassClass: anObject [
metaclassClass := anObject
^ self builderEnhancer metaclassClassFor: self
]

{ #category : 'accessing' }
Expand Down
24 changes: 24 additions & 0 deletions src/Traits-Tests/ShTraitBuilderTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Class {
#name : 'ShTraitBuilderTest',
#superclass : 'ShiftClassBuilderTest',
#category : 'Traits-Tests-ShiftClassInstaller',
#package : 'Traits-Tests',
#tag : 'ShiftClassInstaller'
}

{ #category : 'tests' }
ShTraitBuilderTest >> testRemovingTraitCompositionOfAClassShouldUpdateItsMetaclass [

| t1 newClass |
t1 := (Trait << #TShCITestClass package: self packageNameForTest) install.

newClass := ((Object << #ShCITestClass)
traits: t1;
package: self packageNameForTest) install.

self assert: newClass class class equals: TraitedMetaclass.

newClass := (Object << #ShCITestClass package: self packageNameForTest) install.

self assert: newClass class class equals: Metaclass
]
7 changes: 2 additions & 5 deletions src/Traits/ShiftClassBuilder.extension.st
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ ShiftClassBuilder >> beTrait [

self
superclass: nil;
metaSuperclass: Trait;
metaclassClass: MetaclassForTraits
metaSuperclass: Trait
]

{ #category : '*Traits' }
Expand Down Expand Up @@ -53,9 +52,7 @@ ShiftClassBuilder >> traitComposition [
ShiftClassBuilder >> traitComposition: aValue [

self classTraitComposition: aValue asTraitComposition classComposition.
"Cyril: The next line is for the case where we update a class that had a trait and we remove the used traits. The metaclass should be updated also.
But, IMO we could do better. Instead of having a state for the metaclassClass we should resolve it via the enhancer during the building. And someone could set its own using its own enhancer."
(aValue isEmpty and: [ metaclassClass = TraitedMetaclass ]) ifTrue: [ metaclassClass := Metaclass ].

^ self privateTraitComposition: aValue
]

Expand Down
30 changes: 13 additions & 17 deletions src/Traits/TraitBuilderEnhancer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,10 @@ TraitBuilderEnhancer >> eliminateDuplicates: aSlotCollection withSuperclassSlots
{ #category : 'initialization' }
TraitBuilderEnhancer >> fillBuilder: aBuilder from: aClass [

(aBuilder superclass isNil and: [ aClass superclass isNil ]) ifTrue: [
aBuilder metaSuperclass: aClass class superclass ].
(aBuilder superclass isNil and: [ aClass superclass isNil ]) ifTrue: [ aBuilder metaSuperclass: aClass class superclass ].

aBuilder traitComposition: aClass traitComposition.
aBuilder classTraitComposition: aClass class basicTraitComposition.

aBuilder metaclassClass: aClass class class
aBuilder classTraitComposition: aClass class basicTraitComposition
]

{ #category : 'initialization' }
Expand All @@ -196,6 +193,17 @@ TraitBuilderEnhancer >> isTraitedMetaclass: aBuilder [
^ aBuilder metaclassClass includesBehavior: TraitedMetaclass
]

{ #category : 'class modifications' }
TraitBuilderEnhancer >> metaclassClassFor: aBuilder [

aBuilder metaSuperclass = Trait ifTrue: [ ^ MetaclassForTraits ].

(aBuilder traitComposition asTraitComposition isNotEmpty or: [
aBuilder classTraitComposition asTraitComposition isNotEmpty or: [ aBuilder superclass class class = TraitedMetaclass ] ]) ifTrue: [ ^ TraitedMetaclass ].

^ super metaclassClassFor: aBuilder
]

{ #category : 'events' }
TraitBuilderEnhancer >> migrateInstancesTo: aClass installer: aShiftClassInstaller [

Expand All @@ -206,18 +214,6 @@ TraitBuilderEnhancer >> migrateInstancesTo: aClass installer: aShiftClassInstall
super migrateInstancesTo: aClass installer: aShiftClassInstaller
]

{ #category : 'class modifications' }
TraitBuilderEnhancer >> newMetaclass: aBuilder [

(aBuilder traitComposition asTraitComposition isNotEmpty or: [ aBuilder classTraitComposition asTraitComposition isNotEmpty or: [ aBuilder superclass class class = TraitedMetaclass]])
ifTrue: [ aBuilder metaclassClass: TraitedMetaclass ].

aBuilder metaSuperclass = Trait
ifTrue: [ aBuilder metaclassClass: MetaclassForTraits ].

^ super newMetaclass: aBuilder
]

{ #category : 'class modifications' }
TraitBuilderEnhancer >> propagateChangesToRelatedClasses: newClass builder: aBuilder [

Expand Down

0 comments on commit 06d4052

Please sign in to comment.