pharo-project / pharo

Pharo is a dynamic reflective pure object-oriented language supporting live programming inspired by Smalltalk.
http://pharo.org
Other
1.17k stars 348 forks source link

RB - RBTrait DNU `asTraitComposition` *and* cannot be created easily in `RBNamespace` #16593

Open badetitou opened 1 month ago

badetitou commented 1 month ago

Bug description It is not possible to use a trait made in RB in another entity in the same RB environment. (I cannot create a RBTrait named "TMyTrait", not install in the system yet, and use it in a class "MyClass") We got an error with asTraitComposition

This feature is used by the SmaCC project.

To Reproduce Execute the following code

namespace := RBNamespace new.
change := namespace smaccDefineTrait: [ :builder |
    builder
        name: #TMyTrait;
        package: #HelloWorld;
        beTrait ].

(namespace classNamed: #TMyTrait). "rb-TMyTrait"

namespace defineClass: [ :builder |
    builder
        name: #MyClass;
        traits: { (namespace classNamed: #TMyTrait) };
        package: #HelloWorld ]

You'll notice the method smaccDefineTrait: which is a copy of RBNamespace>>#defineClass: but adapted to create RBTrait (because their is no method to create RBTrait too.

To avoid searching, here is the implementation of RBNamespace>>#smaccDefineTrait: for Pharo12

smaccDefineTrait: aBuilderBlock
    | change newClass newClassName |
    change := changes defineClass: aBuilderBlock.
    newClassName := change changeClassName.
    newClass := self classNamed: newClassName. 
    newClass
        ifNil: [ | newMetaclass |
            self unmarkAsRemoved: newClassName.
            newClass := self rbTraitClass named: newClassName.
            newMetaclass := self rbTraitedMetaclassClass named: newClassName.
            newClass model: self.
            newMetaclass model: self.
            newClasses
                at: newClassName
                put: (Array with: newClass with: newMetaclass) ].
    newClass superclass: nil.
    self rootClasses add: newClass.
    newClass classSide superclass: nil.
    newClass instanceVariableNames: #().
    newClass classVariableNames: #().
    newClass poolDictionaryNames: #().
    newClass packageName: change package.
    ^ change

Expected behavior I believe we should be able to deal with Trait easily in RB and the asTraitComposition should work

Version information:

Expected development cost I don't know, but I can help to reproduce the issue.

Ducasse commented 1 month ago

Pay attention RB never worked with traits.

badetitou commented 1 month ago

Is it something we want? ( Making RB dealing with Traits ) ( I know it can require too much time and so the community has to work on it )