858 |
858 |
859 printStringForBrowserWithSelector:selector |
859 printStringForBrowserWithSelector:selector |
860 "return a printString to represent myself to the user in a browser." |
860 "return a printString to represent myself to the user in a browser." |
861 |
861 |
862 ^ self printStringForBrowserWithSelector:selector inClass:nil |
862 ^ self printStringForBrowserWithSelector:selector inClass:nil |
|
863 ! ! |
|
864 |
|
865 !Explainer class methodsFor:'utilities'! |
|
866 |
|
867 infoStringForClasses:aCollectionOfClasses withPrefix:prefix |
|
868 "get a nice user readable list for some classes. |
|
869 Up to 4 are named, otherwise the count is presented. |
|
870 The prefix can be sth like ' other', ' sub', ' super', |
|
871 ' implementing' etc. Or it can be an empty string. |
|
872 To be shown in the info line at the bottom." |
|
873 |
|
874 |nClassNames sortedByName classNames| |
|
875 |
|
876 aCollectionOfClasses isEmpty ifTrue:[ |
|
877 ^ 'No %1classes' bindWith:prefix. |
|
878 ]. |
|
879 |
|
880 classNames := aCollectionOfClasses asIdentitySet asOrderedCollection collect:[:each | each theNonMetaclass name]. |
|
881 |
|
882 nClassNames := classNames size. |
|
883 |
|
884 nClassNames <= 4 ifTrue:[ |
|
885 nClassNames == 1 ifTrue:[ |
|
886 ^ '%2' "'1 %1class: %2'" bindWith:prefix with:(classNames first allBold). |
|
887 ]. |
|
888 sortedByName := classNames sort. |
|
889 nClassNames == 2 ifTrue:[ |
|
890 ^ '%2 and %3' "'2 %1classes: %2 and %3'" bindWith:prefix |
|
891 with:(sortedByName first allBold) |
|
892 with:(sortedByName second allBold). |
|
893 ]. |
|
894 nClassNames == 3 ifTrue:[ |
|
895 ^ '%2, %3 and %4' "'3 %1classes: %2, %3 and %4'" bindWith:prefix |
|
896 with:(sortedByName first allBold) |
|
897 with:(sortedByName second allBold) |
|
898 with:(sortedByName third allBold). |
|
899 ]. |
|
900 nClassNames == 4 ifTrue:[ |
|
901 ^ '%2, %3, %4 and %5' "'4 %1classes: %2, %3, %4 and %5'" bindWith:prefix |
|
902 with:(sortedByName first allBold) |
|
903 with:(sortedByName second allBold) |
|
904 with:(sortedByName third allBold) |
|
905 with:(sortedByName fourth allBold). |
|
906 ]. |
|
907 ]. |
|
908 ^ '%1 %2classes' bindWith:nClassNames printString allBold with:prefix |
|
909 |
|
910 "Modified: / 27-07-2006 / 10:09:02 / cg" |
|
911 ! ! |
|
912 |
|
913 !Explainer class methodsFor:'utilities'! |
|
914 |
|
915 methodImplementorsInfoFor:aMethod |
|
916 "get something about the implementors of aMethod |
|
917 to be shown in the info line at the bottom" |
|
918 |
|
919 |implementors msg senders msg2| |
|
920 |
|
921 implementors := SystemBrowser |
|
922 findImplementorsOf:aMethod selector |
|
923 in:(environment allClasses) |
|
924 ignoreCase:false. |
|
925 |
|
926 implementors notEmpty ifTrue:[ |
|
927 msg := 'Only implemented here.'. |
|
928 implementors remove:aMethod ifAbsent:nil. |
|
929 implementors notEmpty ifTrue:[ |
|
930 implementors := implementors collect:[:mthd | mthd mclass ? mthd getMclass]. |
|
931 implementors notEmpty ifTrue:[ |
|
932 msg := 'Also implemented in '. |
|
933 msg := msg , (self infoStringForClasses:implementors withPrefix:'other '). |
|
934 msg := msg , '.'. |
|
935 ] |
|
936 ]. |
|
937 ]. |
|
938 |
|
939 false ifTrue:[ "/ too slow |
|
940 senders := SystemBrowser |
|
941 findSendersOf:aMethod selector |
|
942 in:(environment allClasses) |
|
943 ignoreCase:false. |
|
944 senders notEmpty ifTrue:[ |
|
945 msg2 := 'Sent from ' , senders size printString, ' methods.'. |
|
946 ] ifFalse:[ |
|
947 msg2 := 'No senders.'. |
|
948 ]. |
|
949 msg := msg , '/' , msg2 |
|
950 ]. |
|
951 |
|
952 ^ msg |
|
953 ! ! |
|
954 |
|
955 !Explainer class methodsFor:'utilities'! |
|
956 |
|
957 methodInheritanceInfoFor:aMethod |
|
958 |methodsSuperclass inheritedClass msg methodsClass sel mthd| |
|
959 |
|
960 methodsClass := aMethod mclass. |
|
961 methodsClass isNil ifTrue:[^ nil]. |
|
962 |
|
963 methodsSuperclass := methodsClass superclass. |
|
964 methodsSuperclass isNil ifTrue:[^ nil]. |
|
965 |
|
966 sel := aMethod selector. |
|
967 inheritedClass := methodsSuperclass whichClassIncludesSelector:sel. |
|
968 inheritedClass notNil ifTrue:[ |
|
969 mthd := inheritedClass compiledMethodAt:sel. |
|
970 msg := (sel contractTo:30) allBold. |
|
971 (mthd sends:#'subclassResponsibility') ifTrue:[ |
|
972 msg := msg , ' overrides subclassResponsibility in '. |
|
973 ] ifFalse:[ |
|
974 msg := msg , ' overrides implementation in '. |
|
975 ]. |
|
976 msg := msg , inheritedClass name allBold. |
|
977 "/ msg := msg , '.'. |
|
978 ]. |
|
979 |
|
980 ^ msg |
|
981 ! ! |
|
982 |
|
983 !Explainer class methodsFor:'utilities'! |
|
984 |
|
985 methodRedefinitionInfoFor:aMethod |
|
986 "return a user readable string telling in how many subclasses |
|
987 a method is redefined. |
|
988 To be shown in the info line of a browser" |
|
989 |
|
990 |redefiningClasses msg cls| |
|
991 |
|
992 cls := aMethod mclass. |
|
993 cls isNil ifTrue:[^ nil]. |
|
994 |
|
995 redefiningClasses := cls allSubclasses select:[:cls | cls includesSelector:aMethod selector. ]. |
|
996 redefiningClasses size > 0 ifTrue:[ |
|
997 msg := 'redefined in '. |
|
998 msg := msg , (self infoStringForClasses:redefiningClasses withPrefix:'sub'). |
|
999 msg := msg , '.'. |
|
1000 ]. |
|
1001 |
|
1002 ^ msg |
|
1003 ! ! |
|
1004 |
|
1005 !Explainer class methodsFor:'utilities'! |
|
1006 |
|
1007 methodSpecialInfoFor:aMethod |
|
1008 "handles special cases - such as documentation methods" |
|
1009 |
|
1010 |cls sel| |
|
1011 |
|
1012 cls := aMethod mclass. |
|
1013 cls isNil ifTrue:[^ nil]. |
|
1014 sel := aMethod selector. |
|
1015 cls isNil ifTrue:[^ nil]. |
|
1016 |
|
1017 cls isMeta ifTrue:[ |
|
1018 (AbstractSourceCodeManager isVersionMethodSelector:sel) ifTrue:[ |
|
1019 ^ 'The version method is required for the source code repository - do not modify.'. |
|
1020 ]. |
|
1021 sel == #documentation ifTrue:[ |
|
1022 ^ 'ST/X stores documentation in this method (not in comment slots)'. |
|
1023 ]. |
|
1024 ]. |
|
1025 ^ nil |
863 ! ! |
1026 ! ! |
864 |
1027 |
865 !Filename methodsFor:'debugging'! |
1028 !Filename methodsFor:'debugging'! |
866 |
1029 |
867 inspector2TabContentsView |
1030 inspector2TabContentsView |