<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
For the folks that have a substantial interest in using traits for their projects, here is an example view from Squot (i.e. our Git Browser):<div class="mb_sig"></div>
<div><br></div><div><img id="929bafab-c99a-4394-bc61-e6619648a662" src="cid:98d528b7-dc97-47d4-8878-1c2e17faeed5" width="289" height="244"></img><br></div><div><br></div><div><img id="899d996d-55ad-4662-b84c-40f99d481a6d" src="cid:61472192-8507-45a6-8007-e2033fbffb41" width="264" height="183"></img><br></div><div><br></div><div>Since this perspective on classes-and-traits is rather tool-specific, there is no interface in SystemNavigation for that. You can already see that a simple tree is not sufficient to integrate both classes and their traits at the same time.</div><div><br></div><div>Personally, I think that one should try looking for a nice architecture without using traits. Smalltalk tools are sufficient to find protocols that cross-cut the primary decomposition, that is, the class hierarchy. ;o) In Vivide, I added a few traits to document the interface that is necessary to build new visualizations. A simple dummy visualization would have done the same.</div><div><br></div><div>Best,</div><div>Marcel</div><blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
<p style="color: #AAAAAA; margin-top: 10px;">Am 09.12.2021 10:12:45 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">Marcel Taeumel uploaded a new version of Tools to project The Trunk:<br>http://source.squeak.org/trunk/Tools-mt.1085.mcz<br><br>==================== Summary ====================<br><br>Name: Tools-mt.1085<br>Author: mt<br>Time: 9 December 2021, 10:12:31.310176 am<br>UUID: a5c416d3-2818-4a46-abfb-7c524be90692<br>Ancestors: Tools-mt.1084<br><br>Complements an earlier change in HierarchyBrowser to show traits in a hierarchy. Now, for classes, also show the traits they use along with their superclasses.<br><br>=============== Diff against Tools-mt.1084 ===============<br><br>Item was added:<br>+ ----- Method: HierarchyBrowser>>allAncestorsOfClass:withLevelDo: (in category 'hierarchy - classes') -----<br>+ allAncestorsOfClass: class withLevelDo: classAndLevelBlock<br>+ <br>+ self<br>+ allAncestorsOfClass: class<br>+ withLevelDo: classAndLevelBlock<br>+ startingLevel: 1.!<br><br>Item was added:<br>+ ----- Method: HierarchyBrowser>>allAncestorsOfClass:withLevelDo:startingLevel: (in category 'hierarchy - classes') -----<br>+ allAncestorsOfClass: class withLevelDo: classAndLevelBlock startingLevel: level<br>+ <br>+ (class superclass ifNil: [#()] ifNotNil: [:c | {c}]), class traits<br>+ do: [:ancestor |<br>+ ancestor isTrait<br>+ ifTrue: [<br>+ self<br>+ allAncestorsOfTrait: ancestor<br>+ withLevelDo: classAndLevelBlock<br>+ startingLevel: level + 1]<br>+ ifFalse: [<br>+ self<br>+ allAncestorsOfClass: ancestor<br>+ withLevelDo: classAndLevelBlock<br>+ startingLevel: level + 1].<br>+ classAndLevelBlock value: ancestor value: level].!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>allAncestorsOfTrait:withLevelDo: (in category 'hierarchy - traits') -----<br>- ----- Method: HierarchyBrowser>>allAncestorsOfTrait:withLevelDo: (in category 'traits') -----<br> allAncestorsOfTrait: trait withLevelDo: traitAndLevelBlock<br> <br> self<br> allAncestorsOfTrait: trait<br> withLevelDo: traitAndLevelBlock<br> startingLevel: 1.!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>allAncestorsOfTrait:withLevelDo:startingLevel: (in category 'hierarchy - traits') -----<br>- ----- Method: HierarchyBrowser>>allAncestorsOfTrait:withLevelDo:startingLevel: (in category 'traits') -----<br> allAncestorsOfTrait: trait withLevelDo: traitAndLevelBlock startingLevel: level<br> <br> trait traitComposition asTraitComposition traits<br> do: [:ancestor |<br> self<br> allAncestorsOfTrait: ancestor<br> withLevelDo: traitAndLevelBlock<br> startingLevel: level + 1.<br> traitAndLevelBlock value: ancestor value: level].!<br><br>Item was added:<br>+ ----- Method: HierarchyBrowser>>allSuccessorsOfClass:withLevelDo:startingLevel: (in category 'hierarchy - classes') -----<br>+ allSuccessorsOfClass: class withLevelDo: classAndLevelBlock startingLevel: level <br>+ <br>+ classAndLevelBlock value: class value: level.<br>+ (class subclasses sorted: #name ascending)<br>+ do: [:successor |<br>+ self<br>+ allSuccessorsOfClass: successor <br>+ withLevelDo: classAndLevelBlock<br>+ startingLevel: level + 1].!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>allSuccessorsOfTrait:withLevelDo:startingLevel: (in category 'hierarchy - traits') -----<br>- ----- Method: HierarchyBrowser>>allSuccessorsOfTrait:withLevelDo:startingLevel: (in category 'traits') -----<br> allSuccessorsOfTrait: trait withLevelDo: traitAndLevelBlock startingLevel: level <br> <br> traitAndLevelBlock value: trait value: level.<br>+ (trait users "includes classes and traits" sorted: #name ascending)<br>- (trait users sorted: #name ascending)<br> do: [:user |<br> self<br> allSuccessorsOfTrait: user <br> withLevelDo: traitAndLevelBlock<br> startingLevel: level + 1].!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>defineClass:notifying: (in category 'hierarchy - classes') -----<br>- ----- Method: HierarchyBrowser>>defineClass:notifying: (in category 'class functions') -----<br> defineClass: defString notifying: aController <br> <br> super defineClass: defString notifying: aController.<br> self updateAfterClassChange.!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>defineTrait:notifying: (in category 'hierarchy - traits') -----<br>- ----- Method: HierarchyBrowser>>defineTrait:notifying: (in category 'traits') -----<br> defineTrait: defString notifying: aController <br> <br> super defineTrait: defString notifying: aController.<br> self updateAfterClassChange.!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>initHierarchyForClass: (in category 'hierarchy - classes') -----<br>- ----- Method: HierarchyBrowser>>initHierarchyForClass: (in category 'initialization') -----<br> initHierarchyForClass: aClassOrMetaClass <br>+ <br>+ | nonMetaClass baseLevel |<br>- | nonMetaClass superclasses |<br> centralClass := aClassOrMetaClass.<br> nonMetaClass := aClassOrMetaClass theNonMetaClass.<br> self selectEnvironment: aClassOrMetaClass environment.<br> metaClassIndicated := aClassOrMetaClass isMeta.<br> classDisplayList := OrderedCollection new.<br>+ baseLevel := 0.<br>+ self<br>+ allAncestorsOfClass: nonMetaClass<br>+ withLevelDo: [ : each : level | baseLevel := baseLevel max: level ].<br>+ self<br>+ allAncestorsOfClass: nonMetaClass<br>+ withLevelDo:<br>+ [ : classOrTrait : level | | label |<br>+ label := (String streamContents:<br>+ [:stream | baseLevel - level timesRepeat: [ stream nextPutAll: ' ' ].<br>+ stream nextPutAll: classOrTrait name ]).<br>+ classOrTrait isTrait<br>+ ifTrue: [ label := label asText addAttribute: TextEmphasis italic ].<br>+ classDisplayList add: label ].<br>+ self<br>+ allSuccessorsOfClass: nonMetaClass<br>+ withLevelDo:<br>+ [ : each : level | classDisplayList add:<br>- (superclasses := nonMetaClass allSuperclasses reversed) withIndexDo:<br>- [ : each : indent | classDisplayList add:<br>- (String streamContents:<br>- [ : stream | indent - 1 timesRepeat: [ stream nextPutAll: ' ' ].<br>- stream nextPutAll: each name ]) ].<br>- nonMetaClass<br>- allSubclassesWithLevelDo:<br>- [ : eachClass : lvl | classDisplayList add:<br> (String streamContents:<br>+ [ : stream | level timesRepeat: [ stream nextPutAll: ' ' ].<br>+ stream nextPutAll: each name ]) ]<br>+ startingLevel: baseLevel.<br>- [ : stream | lvl timesRepeat: [ stream nextPutAll: ' ' ].<br>- stream nextPutAll: eachClass name ]) ]<br>- startingLevel: superclasses size.<br> <br> self changed: #classList.<br>+ self selectClass: nonMetaClass.!<br>- self selectClass: nonMetaClass!<br><br>Item was changed:<br>+ ----- Method: HierarchyBrowser>>initHierarchyForTrait: (in category 'hierarchy - traits') -----<br>- ----- Method: HierarchyBrowser>>initHierarchyForTrait: (in category 'traits') -----<br> initHierarchyForTrait: baseTraitOrClassTrait<br> <br> | baseTrait baseLevel |<br> centralClass := baseTraitOrClassTrait.<br> baseTrait := baseTraitOrClassTrait baseTrait.<br> self selectEnvironment: baseTraitOrClassTrait environment.<br> metaClassIndicated := baseTraitOrClassTrait isClassTrait.<br> classDisplayList := OrderedCollection new.<br> baseLevel := 0.<br> self<br> allAncestorsOfTrait: baseTrait<br>+ withLevelDo: [ : each : level | baseLevel := baseLevel max: level ].<br>- withLevelDo: [:each :level | baseLevel := baseLevel max: level].<br> self<br> allAncestorsOfTrait: baseTrait<br> withLevelDo:<br> [:each :level | classDisplayList add:<br> (String streamContents:<br> [ : stream | baseLevel - level timesRepeat: [ stream nextPutAll: ' ' ].<br> stream nextPutAll: each name ]) ].<br> self<br> allSuccessorsOfTrait: baseTrait<br> withLevelDo:<br>+ [:classOrTrait :level | | label |<br>+ label := (String streamContents:<br>- [:each :level | classDisplayList add:<br>- (String streamContents:<br> [ : stream | level timesRepeat: [ stream nextPutAll: ' ' ].<br>+ stream nextPutAll: classOrTrait name ]).<br>+ classOrTrait isTrait<br>+ ifFalse: [ label := label asText addAttribute: TextEmphasis italic ].<br>+ classDisplayList add: label ]<br>- stream nextPutAll: each name ]) ]<br> startingLevel: baseLevel.<br> <br> self changed: #classList.<br> self selectClass: baseTrait.!<br><br><br></div></blockquote></div>