<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        Hi all! :-)<div><br></div><div>Can you please test your usual search patterns and report back?</div><div><br></div><div>Thanks,</div><div>Marcel</div><div class="mb_sig"></div><blockquote class="history_container" type="cite" style="border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 11.07.2019 08:50:35 schrieb commits@source.squeak.org <commits@source.squeak.org>:</p><div style="font-family:Arial,Helvetica,sans-serif">A new version of ToolBuilder-Kernel was added to project The Inbox:<br>http://source.squeak.org/inbox/ToolBuilder-Kernel-mt.125.mcz<br><br>==================== Summary ====================<br><br>Name: ToolBuilder-Kernel-mt.125<br>Author: mt<br>Time: 11 July 2019, 8:50:30.487838 am<br>UUID: 3f3a21f8-a141-734f-8aed-f0c21aff22b9<br>Ancestors: ToolBuilder-Kernel-mt.124<br><br>Updates the search for class names using the new find-features feature on strings. Find WeakIdentityKeyDictionary (in a small list of results) with any of the following patterns:<br><br>WKD<br>Weak*Dict*<br>WeakDict<br>WeakIdentityKeyDictionary<br><br>=============== Diff against ToolBuilder-Kernel-mt.124 ===============<br><br>Item was changed:<br>  ----- Method: UIManager>>classOrTraitFrom:pattern:label: (in category 'system introspecting') -----<br>  classOrTraitFrom: environment pattern: pattern label: label<br>+        "Given a pattern and an environment, try to find a class or trait using several strategies:<br>+             - EXACT: If there is a class or trait whose name exactly given by pattern, return it.<br>+                - UPPER: If the pattern is upper-case only, find camel-case letters with that sequence.<br>+              - WILD: Try the pattern as-is for regular wild-card search.<br>+          - FEATURE: Split patterns at feature boundaries and insert wild cards between.<br>+               - FUZZY: Split patterns at feature boundaries BUT treat each feature as a full class name.<br>+   If there is only one class or trait in the given environment whose name matches pattern, return it. Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.<br>-  "If there is a class or trait whose name exactly given by pattern, return it.<br>-   If there is only one class or trait in the given environment whose name matches pattern, return it.<br>-  Otherwise, put up a menu offering the names of all classes that match pattern, and return the class chosen, else nil if nothing chosen.<br>-      This method ignores separator characters in the pattern"<br>         <br>+     !!!! In any case, separator characters in the pattern are ignored."<br>+     <br>+     | toMatch potentialNames names selectedIndex |<br>+       <br>+     "If there's a class or trait named as pattern, then return it."<br>+    (environment classOrTraitNamed: pattern) ifNotNil: [:classOrTrait | ^ classOrTrait].<br>+ <br>+     "Validate pattern."   <br>-     | toMatch potentialNames names exactMatch lines reducedIdentifiers selectedIndex |<br>    toMatch := pattern copyWithoutAll: Character separators.<br>+     toMatch := toMatch asLowercase copyWithout: $..<br>       toMatch ifEmpty: [ ^nil ].<br>+ <br>+       "Fetch search space."<br>+      names := OrderedCollection new.<br>+      potentialNames := environment classAndTraitNames asOrderedCollection.<br>+ <br>+    "Try uppercase-only patterns for patterns such as 'WKD' to find 'WeakIdentityKeyDictionary' etc."<br>+  names ifEmpty: [<br>+             (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [<br>+                   potentialNames do: [:each |<br>+                          | patternStream |<br>+                            patternStream := pattern readStream.<br>+                                 each detect: [:char |<br>+                                        (patternStream atEnd not and: [patternStream peek = char])<br>+                                           ifTrue: [<br>+                                                    patternStream next.<br>+                                                  patternStream atEnd<br>+                                                          ifTrue: [names add: each. true "Match!!"]<br>+                                                          ifFalse: [false "Not yet..."]]<br>+                                             ifFalse: [false "No match..."] ] ifNone: [] ] ]].<br>+ <br>+      "Try wildcard search for patterns such as 'Weak*Dict*' to find 'WeakIdentityKeyDictionary' etc."<br>+   names ifEmpty: [<br>+             names := potentialNames select: [ :each | toMatch match: each ]].<br>-    "If there's a class or trait named as pattern, then return it."<br>-    Symbol hasInterned: pattern ifTrue: [ :symbol |<br>-              environment at: symbol ifPresent: [ :maybeClassOrTrait |<br>-                     ((maybeClassOrTrait isKindOf: Class) or: [<br>-                           maybeClassOrTrait isTrait ])<br>-                                         ifTrue: [ ^maybeClassOrTrait ] ] ].<br>-  "No exact match, look for potential matches."<br>-      toMatch := pattern asLowercase copyWithout: $..<br>-      potentialNames := (environment classAndTraitNames) asOrderedCollection.<br>-      names := pattern last = $. "This is some old hack, using String>>#match: may be better."<br>-             ifTrue: [ potentialNames select: [ :each | each asLowercase = toMatch ] ]<br>-            ifFalse: [<br>-                   potentialNames select: [ :each |<br>-                             each includesSubstring: toMatch caseSensitive: false ] ].<br>-    exactMatch := names detect: [ :each | each asLowercase = toMatch ] ifNone: [ nil ].<br>-  lines := OrderedCollection new.<br>-      exactMatch ifNotNil: [ lines add: 1 ].<br>-       "Also try some fuzzy matching."<br>-    reducedIdentifiers := pattern suggestedTypeNames select: [ :each |<br>-           potentialNames includes: each ].<br>-     reducedIdentifiers ifNotEmpty: [<br>-             names addAll: reducedIdentifiers.<br>-            lines add: 1 + names size + reducedIdentifiers size ].<br>-       "Let the user select if there's more than one possible match. This may give surprising results."<br>-   names size = 0 ifTrue: [^ nil "nothing matches"].<br>   <br>+     "Try feature-based search for patterns such as 'WeakDict' to find 'WeakIdentityKeyDictionary' etc."<br>+        names ifEmpty: [<br>+             toMatch := pattern copyWithoutAll: '.*#'.<br>+            toMatch findFeatures in: [:features |<br>+                        "1) Insert wildcards between features and at the end."<br>+                     toMatch := (features joinSeparatedBy: '*'), '*'.<br>+                     names := potentialNames select: [ :each | toMatch match: each ].<br>+                     names ifEmpty: [        <br>+                             "2) Insert wildcards before, between, and after features."<br>+                                 toMatch := '*', (features joinSeparatedBy: '*'), '*'.<br>+                                names := potentialNames select: [ :each | toMatch match: each ] ]] ].<br>+        <br>+     "Try some fuzzy matching."<br>+         names addAll: (pattern suggestedTypeNames select: [ :each | potentialNames includes: each ]).<br>+        <br>+     "Still no match?"<br>+  names ifEmpty: [ ^ nil ].<br>+ <br>+        "Let the user select if there's more than one possible match. This may give surprising results."      <br>      selectedIndex := names size = 1<br>               ifTrue: [ 1 ]<br>+                ifFalse: [ self chooseFrom: names title: label ].<br>-            ifFalse: [<br>-                   exactMatch ifNotNil: [ names addFirst: exactMatch ].<br>-                         self chooseFrom: names lines: lines title: label ].<br>   selectedIndex = 0 ifTrue: [ ^nil ].<br>   ^environment at: (names at: selectedIndex) asSymbol!<br><br><br></div></blockquote>
                                        </div></body>