Patrick Rein uploaded a new version of Tools to project The Trunk: http://source.squeak.org/trunk/Tools-pre.1077.mcz
==================== Summary ====================
Name: Tools-pre.1077 Author: pre Time: 29 November 2021, 11:53:31.567297 am UUID: d1d2b6a9-1db1-1947-b4b6-5a57fd00945d Ancestors: Tools-mt.1076
Slightly improves the documentation of the dependency browser and refactors the dependency computation by splitting it up into single methods describing the individual steps.
=============== Diff against Tools-mt.1076 ===============
Item was changed: CodeHolder subclass: #DependencyBrowser instanceVariableNames: 'packageList packageDeps packageDepsList classDeps classDepsList classList messageList packageListIndex packageDepsIndex classDepsIndex classListIndex messageListIndex autoSelectString windowTitle' classVariableNames: '' poolDictionaries: '' category: 'Tools-Browser'!
+ !DependencyBrowser commentStamp: 'pre 11/29/2021 11:48' prior: 0! - !DependencyBrowser commentStamp: 'fbs 5/6/2011 11:29' prior: 0! A simple dependency browser showing five panes: [1]: Packages: The list of available packages in the system. + [2]: Package Dependencies: The packages the currently selected package depends on. + [3]: Class Dependencies: The classes the currently selected package [1] depends on (filtered by the selected required package [2]). + [4]: Class List: The classes in the currently selected package [1] containing the references to the class dependencies [3]. + [5]: Messages: The messages in the currently selected package [1] and class [4] that contain the references to the class dependencies [3]. + + # Implementation + The dependencies are pre-computed whenever the selected package changes [1], see #computePackageAndClassDependencies.! - [2]: Package Dependencies: The dependent packages of the currently selected package. - [3]: Class Dependencies: The classes causing the dependencies. - [4]: Class List: The classes introducing the dependencies. - [5]: Messages: The messages introducing the dependencies.!
Item was changed: ----- Method: DependencyBrowser class>>openInvertedOn: (in category 'opening') ----- openInvertedOn: requiredPackageNames "DependencyBrowser openInvertedOn: #(Monticello)" | model | model := self new. ^ ToolBuilder open: ( model packageList: (model packageList select: [:packageName | + model computePackageAndClassDependencies: packageName. - model computePackageDependencies: packageName. model packageDeps includesAnyOf: requiredPackageNames]); windowTitle: ('Dependency Browser (inverted on {1})' format: {requiredPackageNames}); yourself) !
Item was changed: + ----- Method: DependencyBrowser>>classDeps (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDeps (in category 'class deps') ----- classDeps "Class dependencies for the currently selected package" packageDeps ifNil: [^ #()]. ^ (packageDeps at: self packageDepsSelection ifAbsent:[#()]) sort. !
Item was changed: + ----- Method: DependencyBrowser>>classDepsIndex (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsIndex (in category 'class deps') ----- classDepsIndex "Class dependency selection" ^classDepsIndex ifNil:[0]!
Item was changed: + ----- Method: DependencyBrowser>>classDepsIndex: (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsIndex: (in category 'class deps') ----- classDepsIndex: idx "Class dependency selection" classDepsIndex := idx. self changed: #classDepsIndex. classList := nil. self changed: #classList. self classListIndex: (idx = 0 ifTrue: [0] ifFalse: [1]).!
Item was changed: + ----- Method: DependencyBrowser>>classDepsKey:from: (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsKey:from: (in category 'class deps') ----- classDepsKey: aCharacter from: aPluggableListMorphPlus aCharacter = $N ifTrue: [^ self referencesToIt: (self classDeps at: self classDepsIndex)].!
Item was changed: + ----- Method: DependencyBrowser>>classDepsList (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsList (in category 'class deps') ----- classDepsList "Class dependencies for the currently selected package"
| checkDef checkExt | checkDef := [:mref | mref selector = #Definition]. checkExt := [:mref | mref category notNil and: [mref category first = $*]]. ^ classDepsList ifNil: [ classDepsList := self classDeps. classDepsList := classDepsList collect: [:className | String streamContents: [:label | label nextPutAll: className. (self depsForClassNamed: className allSatisfy: checkDef) ifTrue: [label nextPutAll: ' (defs only)'] ifFalse: [(self depsForClassNamed: className allSatisfy: checkExt) ifTrue: [label nextPutAll: ' *exts only'] ifFalse: [ (self depsForClassNamed: className anySatisfy: checkDef) ifTrue: [label nextPutAll: ' ()']. (self depsForClassNamed: className anySatisfy: checkExt) ifTrue: [label nextPutAll: ' *']]]]]]!
Item was changed: + ----- Method: DependencyBrowser>>classDepsMenu: (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsMenu: (in category 'class deps') ----- classDepsMenu: aMenu ^aMenu!
Item was changed: + ----- Method: DependencyBrowser>>classDepsSelection (in category 'class dependencies') ----- - ----- Method: DependencyBrowser>>classDepsSelection (in category 'class deps') ----- classDepsSelection "Class dependency selection" ^(self classDepsIndex between: 1 and: self classDeps size) ifTrue:[self classDeps at: self classDepsIndex].!
Item was added: + ----- Method: DependencyBrowser>>computeClassDependenciesFor: (in category 'private - dependencies') ----- + computeClassDependenciesFor: packageInfo + + packageInfo classes do: [:pkgClass | + "Add the superclass and SharedPools as dependencies." + (classDeps at: (pkgClass superclass ifNil: [ProtoObject]) name + ifAbsentPut: [OrderedCollection new]) add: + (MethodReference class: pkgClass selector: #Definition). + pkgClass sharedPools do: [:sharedPool | + sharedPool isBehavior ifTrue: [ + (classDeps at: sharedPool name + ifAbsentPut: [OrderedCollection new]) add: + (MethodReference class: pkgClass selector: #Definition)]]]. + + packageInfo coreMethods do: [:mref | + mref compiledMethod allLiteralsDo: [:lit | + (lit isVariableBinding and: [lit value isBehavior]) ifTrue: [ + (classDeps at: lit value name ifAbsentPut: [OrderedCollection new]) + add: mref]]]. + + packageInfo extensionMethods do: [:mref | + (classDeps at: mref actualClass name ifAbsentPut: [OrderedCollection new]) + add: mref]. + !
Item was added: + ----- Method: DependencyBrowser>>computePackageAndClassDependencies: (in category 'private - dependencies') ----- + computePackageAndClassDependencies: pkgName + "Compute the dependencies for the given package" + | packageInfo | + classDeps := Dictionary new. + packageDeps := Dictionary new. + pkgName ifNil: [^ self]. + packageInfo := PackageOrganizer default + packageNamed: pkgName + ifAbsent:["unloaded" ^ self]. + + self + computeClassDependenciesFor: packageInfo; + computePackageDependencies. + + (packageDeps removeKey: pkgName ifAbsent: [#()]) do: [:each | + classDeps removeKey: each ifAbsent: []].!
Item was added: + ----- Method: DependencyBrowser>>computePackageDependencies (in category 'private - dependencies') ----- + computePackageDependencies + + classDeps keys do:[:className| | aClass pkg | + aClass := Smalltalk classNamed: className. + pkg := aClass ifNil: [nil] ifNotNil: [PackageOrganizer default packageOfClass: aClass ifNone:[nil]]. + pkg + ifNil:[ + Transcript cr; show: 'WARNING: No package for ', className. + (classDeps removeKey: className) do:[:each| Transcript crtab; show: each]] + ifNotNil:[ + (packageDeps at: pkg name ifAbsentPut:[OrderedCollection new]) add: className]].!
Item was removed: - ----- Method: DependencyBrowser>>computePackageDependencies: (in category 'package deps') ----- - computePackageDependencies: pkgName - "Compute the dependencies for the given package" - | pi | - classDeps := Dictionary new. - packageDeps := Dictionary new. - pkgName ifNil:[^self]. - pi := PackageOrganizer default packageNamed: pkgName ifAbsent:[^self]. "unloaded" - pi classes do:[:pkgClass | - (classDeps at: (pkgClass superclass ifNil:[ProtoObject]) name - ifAbsentPut:[OrderedCollection new]) add: - (MethodReference class: pkgClass selector: #Definition). - pkgClass sharedPools do: [:sharedPool | - sharedPool isBehavior ifTrue: [ - (classDeps at: sharedPool name - ifAbsentPut:[OrderedCollection new]) add: - (MethodReference class: pkgClass selector: #Definition)]]]. - - pi coreMethods do:[:mref| - mref compiledMethod allLiteralsDo:[:lit | - (lit isVariableBinding and: [lit value isBehavior]) ifTrue:[ - (classDeps at: lit value name ifAbsentPut:[OrderedCollection new]) - add: mref]]]. - - pi extensionMethods do:[:mref| - (classDeps at: mref actualClass name ifAbsentPut: [OrderedCollection new]) - add: mref]. - - classDeps keys do:[:className| | aClass pkg | - aClass := Smalltalk classNamed: className. - pkg := aClass ifNil: [nil] ifNotNil: [PackageOrganizer default packageOfClass: aClass ifNone:[nil]]. - pkg ifNil:[ - Transcript cr; show: 'WARNING: No package for ', className. - (classDeps removeKey: className) do:[:each| Transcript crtab; show: each]. - ] ifNotNil:[ - (packageDeps at: pkg name ifAbsentPut:[OrderedCollection new]) add: className. - ]. - ]. - - (packageDeps removeKey: pkgName ifAbsent:[#()]) do:[:each| - classDeps removeKey: each ifAbsent:[]. - ].!
Item was changed: + ----- Method: DependencyBrowser>>packageDeps (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDeps (in category 'package deps') ----- packageDeps "Package dependencies for the currently selected package" packageDeps ifNil:[ packageDeps := Dictionary new. Cursor wait showWhile:[ + self computePackageAndClassDependencies: self packageListSelection. - self computePackageDependencies: self packageListSelection. ]. ]. ^packageDeps keys sort!
Item was changed: + ----- Method: DependencyBrowser>>packageDepsIndex (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDepsIndex (in category 'package deps') ----- packageDepsIndex "Current package dependencies selection" ^packageDepsIndex ifNil:[0]!
Item was changed: + ----- Method: DependencyBrowser>>packageDepsIndex: (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDepsIndex: (in category 'package deps') ----- packageDepsIndex: aNumber "Current package dependencies selection" packageDepsIndex := aNumber. self changed: #packageDepsIndex. classDepsList := nil. self changed: #classDepsList. self classDepsIndex: (aNumber = 0 ifTrue: [0] ifFalse: [1]). !
Item was changed: + ----- Method: DependencyBrowser>>packageDepsList (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDepsList (in category 'package deps') ----- packageDepsList "Package dependencies for the currently selected package" | checkDef checkExt | checkDef := [:mref | mref selector = #Definition]. checkExt := [:mref | mref category notNil and: [mref category first = $*]]. ^ packageDepsList ifNil: [ packageDepsList := self packageDeps. packageDepsList := packageDepsList collect: [:packageName | String streamContents: [:label | label nextPutAll: packageName. (self depsForPackageNamed: packageName allSatisfy: checkDef) ifTrue: [label nextPutAll: ' (defs only)'] ifFalse: [(self depsForPackageNamed: packageName allSatisfy: checkExt) ifTrue: [label nextPutAll: ' *exts only'] ifFalse: [ (self depsForPackageNamed: packageName anySatisfy: checkDef) ifTrue: [label nextPutAll: ' ()']. (self depsForPackageNamed: packageName anySatisfy: checkExt) ifTrue: [label nextPutAll: ' *']]]]]]!
Item was changed: + ----- Method: DependencyBrowser>>packageDepsMenu: (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDepsMenu: (in category 'package deps') ----- packageDepsMenu: aMenu ^aMenu!
Item was changed: + ----- Method: DependencyBrowser>>packageDepsSelection (in category 'package dependencies') ----- - ----- Method: DependencyBrowser>>packageDepsSelection (in category 'package deps') ----- packageDepsSelection "Current package dependencies selection" ^(self packageDepsIndex between: 1 and: self packageDeps size) ifTrue:[self packageDeps at: self packageDepsIndex]!
Item was changed: ----- Method: DependencyBrowser>>selectedMessage (in category 'contents') ----- selectedMessage "Source code for currently selected message" | className methodName mref | className := self classListSelection. methodName := self messageListSelection. mref := (classDeps at: self classDepsSelection ifAbsent:[#()]) detect:[:mr| mr actualClass name = className and:[mr methodSymbol = methodName]] ifNone:[nil]. + mref ifNil:[^ self class comment]. + mref methodSymbol == #Definition ifTrue:[^ mref actualClass definition]. - mref ifNil:[^self class comment]. - mref methodSymbol == #Definition ifTrue:[^mref actualClass definition]. ^mref sourceCode!
packages@lists.squeakfoundation.org