<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mer. 17 juil. 2019 à 08:18, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Marcel Taeumel uploaded a new version of ToolBuilder-Kernel to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/ToolBuilder-Kernel-ul.128.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/ToolBuilder-Kernel-ul.128.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: ToolBuilder-Kernel-ul.128<br>
Author: ul<br>
Time: 16 July 2019, 11:36:38.782463 pm<br>
UUID: 7153b8e4-a085-4af2-b2a8-3f14585475b0<br>
Ancestors: ToolBuilder-Kernel-mt.127<br>
<br>
Further improvements:<br>
- do not convert potentialNames from Array to OrderedCollection<br>
- removed unnecessary ifEmpty: check<br>
- use #indexOf:startingAt: to search for a single character in a string<br>
- applied JIT tricks<br>
- simplified/restructured wildcard/feature-based searches<br>
<br>
Ideas not implemented:<br>
- suggestedTypeNames could become suggestedTypeNamesDo:<br>
<br>
=============== Diff against ToolBuilder-Kernel-mt.127 ===============<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>
<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 := pattern copyWithoutAll: Character separators.<br></blockquote><div>Note that pattern copyWithoutAll: CharacterSet separators is a tiny bit faster than Character separators.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
toMatch := toMatch asLowercase copyWithout: $..<br>
toMatch ifEmpty: [ ^nil ].<br>
<br>
"Fetch search space."<br>
names := OrderedCollection new.<br>
+ potentialNames := environment classAndTraitNames.<br>
- potentialNames := environment classAndTraitNames asOrderedCollection.<br>
<br>
"Try uppercase-only patterns for patterns such as 'WKD' to find 'WeakIdentityKeyDictionary' etc."<br>
+ (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [<br>
+ | patternSize |<br>
+ patternSize := pattern size.<br>
+ potentialNames do: [ :eachName | <br>
+ | lookupIndex characterIndex |<br>
+ lookupIndex := 0.<br>
+ characterIndex := 1.<br>
+ [ (lookupIndex := eachName<br>
+ indexOf: (pattern at: characterIndex)<br>
+ startingAt: lookupIndex + 1) > 0<br>
+ and: [ (characterIndex := characterIndex + 1) <= patternSize ] ] whileTrue.<br>
+ lookupIndex > 0 ifTrue: [ names add: eachName ] ] ].<br>
- names ifEmpty: [<br>
- (pattern allSatisfy: [:char | char isUppercase]) ifTrue: [ <br>
- (potentialNames do: [:eachName | <br>
- | isMatch lookupIndex |<br>
- isMatch := true.<br>
- lookupIndex := 0.<br>
- 1 to: pattern size do: [:charIndex | | char |<br>
- char := pattern at: charIndex.<br>
- isMatch ifTrue: [<br>
- lookupIndex := (eachName findString: char asString startingAt: lookupIndex+1 caseSensitive: true).<br>
- isMatch := lookupIndex > 0]].<br>
- isMatch ifTrue: [names add: eachName] ])]].<br>
<br>
"Try wildcard search for patterns such as 'Weak*Dict*' to find 'WeakIdentityKeyDictionary' etc."<br>
names ifEmpty: [<br>
+ potentialNames do: [ :each | (toMatch match: each) ifTrue: [ names add: each ] ].<br>
+ "Try feature-based search for patterns such as 'WeakDict' to find 'WeakIdentityKeyDictionary' etc."<br>
+ names ifEmpty: [<br>
- potentialNames do: [ :each | (toMatch match: each) ifTrue: [names add: each] ]].<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 := ((pattern copyWithoutAll: '.*#') findFeatures joinSeparatedBy: '*'), '*'.<br>
+ potentialNames do: [ :each | (toMatch match: each) ifTrue: [ names add: each ] ].<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 := '*', toMatch.<br>
+ potentialNames do: [ :each | (toMatch match: each) ifTrue: [ names add: each ] ] ] ] ].<br>
- toMatch := '*', (features joinSeparatedBy: '*'), '*'.<br>
- names := potentialNames select: [ :each | toMatch match: each ] ]] ].<br>
<br>
"Try some fuzzy matching."<br>
+ pattern suggestedTypeNames do: [ :each |<br>
+ (potentialNames includes: each) ifTrue: [ names add: each ] ].<br>
- names addAll: (pattern suggestedTypeNames select: [ :each | potentialNames includes: each ]).<br>
<br>
"Still no match?"<br>
+ names ifEmpty: [ ^nil ].<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>
selectedIndex = 0 ifTrue: [ ^nil ].<br>
^environment at: (names at: selectedIndex) asSymbol!<br>
<br>
<br>
</blockquote></div></div>