5145 |
5145 |
5146 searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase |
5146 searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase |
5147 ^ self searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase match:true |
5147 ^ self searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase match:true |
5148 ! |
5148 ! |
5149 |
5149 |
5150 searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase match:doMatch |
5150 searchBlockForAllCallsOn:aSelectorString ignoreCase:ignoreCase match:doMatchArg |
5151 |sel searchBlock lcString quickMatch| |
5151 "return an optimized search block for the senders search. |
5152 |
5152 Because this highly affects the speed of the senders-search in the browser, |
5153 ((doMatch |
5153 specialized blocks are returned, depending on whether a selector-match or casesensitive |
5154 and:[(aSelectorString ~= '*') |
5154 search is wanted |
5155 and:[aSelectorString includesMatchCharacters]]) |
5155 (these operations are executed a zillion times in an inner loop, |
5156 or:[ignoreCase]) ifTrue:[ |
5156 therefore, the speedup is noticable)" |
|
5157 |
|
5158 |doMatch sel lcString quickSearch| |
|
5159 |
|
5160 doMatch := doMatchArg. |
|
5161 (doMatch and:[aSelectorString = '*']) ifTrue:[ |
|
5162 "a trivial block, which matches everything" |
|
5163 ^ [:class :method :s | true]. |
|
5164 ]. |
|
5165 |
|
5166 aSelectorString includesMatchCharacters ifFalse:[ |
|
5167 doMatch := false |
|
5168 ]. |
|
5169 |
|
5170 (doMatch or:[ignoreCase]) ifTrue:[ |
5157 "/ a matchString or ignoreCase - need string matching procedure |
5171 "/ a matchString or ignoreCase - need string matching procedure |
5158 |
5172 |
5159 ignoreCase ifTrue:[ |
5173 ignoreCase ifTrue:[ |
5160 lcString := aSelectorString asLowercase. |
5174 lcString := aSelectorString asLowercase. |
5161 ] ifFalse:[ |
5175 ] ifFalse:[ |
5162 lcString := aSelectorString. |
5176 lcString := aSelectorString. |
5163 ]. |
5177 ]. |
5164 |
5178 |
5165 quickMatch := aSelectorString. |
5179 quickSearch := aSelectorString. |
5166 (quickMatch startsWith:'*') ifTrue:[ |
5180 (quickSearch startsWith:'*') ifTrue:[ |
5167 quickMatch := quickMatch copyButFirst |
5181 quickSearch := quickSearch copyButFirst |
5168 ]. |
5182 ]. |
5169 (quickMatch endsWith:'*') ifTrue:[ |
5183 (quickSearch endsWith:'*') ifTrue:[ |
5170 quickMatch := quickMatch copyButLast |
5184 quickSearch := quickSearch copyButLast |
5171 ]. |
5185 ]. |
5172 (quickMatch includes:$:) ifTrue:[ |
5186 (quickSearch includes:$:) ifTrue:[ |
5173 quickMatch := quickMatch copyTo:(quickMatch indexOf:$:)-1. |
5187 quickSearch := quickSearch copyTo:(quickSearch indexOf:$:)-1. |
5174 ]. |
5188 ]. |
5175 |
5189 |
5176 (ignoreCase not and:[quickMatch includesMatchCharacters not]) ifTrue:[ |
5190 (ignoreCase and:[quickSearch includesMatchCharacters not]) ifTrue:[ |
5177 searchBlock := [:class :methodArg :s | |
5191 doMatch ifFalse:[ |
5178 |method src inLiterals| |
5192 ^ [:class :methodArg :s | |
5179 |
5193 |method src inLiterals lcQuickSearch| |
5180 inLiterals := false. |
5194 |
5181 method := methodArg originalMethodIfWrapped. |
5195 inLiterals := false. |
5182 method isLazyMethod ifTrue:[ |
5196 method := methodArg originalMethodIfWrapped. |
5183 src := method source. |
5197 method isLazyMethod ifTrue:[ |
5184 (src notNil and:[src includesString:quickMatch]) ifTrue:[ |
5198 src := method source. |
5185 method makeRealMethod. |
5199 (src notNil and:[src includesString:aSelectorString caseSensitive:false]) ifTrue:[ |
5186 inLiterals := (method |
5200 method makeRealMethod. |
5187 literalsDetect:[:aLiteral| |
5201 inLiterals := (method |
5188 (aLiteral isMemberOf:Symbol) |
5202 literalsDetect:[:aLiteral| |
5189 and:[(lcString includesString:quickMatch) |
5203 (aLiteral isMemberOf:Symbol) |
5190 and:[(lcString match:aLiteral)]]] |
5204 and:[(aLiteral sameAs:aSelectorString)]] |
5191 ifNone:nil) notNil |
5205 ifNone:nil) notNil |
5192 ] |
5206 ] |
5193 ] ifFalse:[ |
5207 ] ifFalse:[ |
5194 inLiterals := (method |
5208 inLiterals := (method |
5195 literalsDetect:[:aLiteral| |
5209 literalsDetect:[:aLiteral| |
5196 (aLiteral isMemberOf:Symbol) |
5210 (aLiteral isMemberOf:Symbol) |
5197 and:[(lcString includesString:quickMatch) |
5211 and:[(aLiteral sameAs:aSelectorString)]] |
5198 and:[(lcString match:aLiteral)]]] |
5212 ifNone:nil) notNil |
5199 ifNone:nil) notNil |
5213 ]. |
5200 ]. |
5214 |
5201 inLiterals |
5215 inLiterals |
5202 and:[ method messagesSent |
5216 and:[ |
5203 contains:[:anySelector | aSelectorString match:anySelector caseSensitive:ignoreCase not] ] |
5217 method messagesSent contains:[:msg | msg sameAs:aSelectorString ] |
5204 ]. |
5218 ] |
5205 ] ifFalse:[ |
5219 ]. |
5206 searchBlock := [:class :methodArg :s | |
5220 ]. |
5207 |method src inLiterals| |
5221 |
5208 |
5222 ^ [:class :methodArg :s | |
5209 method := methodArg originalMethodIfWrapped. |
5223 |method src inLiterals lcQuickSearch| |
5210 "/ expensive search |
5224 |
5211 inLiterals := false. |
5225 inLiterals := false. |
5212 method isLazyMethod ifTrue:[ |
5226 method := methodArg originalMethodIfWrapped. |
5213 src := method source. |
5227 method isLazyMethod ifTrue:[ |
5214 (src notNil and:[src includesMatchString:aSelectorString]) ifTrue:[ |
5228 src := method source. |
5215 method makeRealMethod. |
5229 (src notNil and:[src includesString:quickSearch caseSensitive:false]) ifTrue:[ |
5216 inLiterals := (method |
5230 method makeRealMethod. |
5217 literalsDetect:[:aLiteral| |
5231 inLiterals := (method |
5218 (aLiteral isMemberOf:Symbol) |
5232 literalsDetect:[:aLiteral| |
5219 and:[(ignoreCase and:[lcString match:aLiteral asLowercase]) |
5233 (aLiteral isMemberOf:Symbol) |
5220 or:[ignoreCase not and:[lcString match:aLiteral]]]] |
5234 and:[(aLiteral includesString:quickSearch caseSensitive:false) |
5221 ifNone:nil) notNil |
5235 and:[(lcString match:aLiteral caseSensitive:false)]]] |
5222 ] |
5236 ifNone:nil) notNil |
5223 ] ifFalse:[ |
5237 ] |
5224 inLiterals := (method literalsDetect:[:aLiteral| |
5238 ] ifFalse:[ |
5225 (aLiteral isMemberOf:Symbol) |
5239 inLiterals := (method |
5226 and:[(ignoreCase and:[lcString match:aLiteral asLowercase]) |
5240 literalsDetect:[:aLiteral| |
5227 or:[ignoreCase not and:[lcString match:aLiteral]]]] |
5241 (aLiteral isMemberOf:Symbol) |
5228 ifNone:nil) notNil |
5242 and:[(aLiteral includesString:quickSearch caseSensitive:false) |
5229 ]. |
5243 and:[(lcString match:aLiteral caseSensitive:false)]]] |
5230 inLiterals |
5244 ifNone:nil) notNil |
5231 and:[ method messagesSent |
5245 ]. |
5232 contains:[:anySelector | aSelectorString match:anySelector caseSensitive:ignoreCase not] ] |
5246 |
5233 ]. |
5247 inLiterals |
|
5248 and:[ |
|
5249 method messagesSent contains:[:sel | aSelectorString match:aSelectorString caseSensitive:false] |
|
5250 ] |
|
5251 ]. |
5234 ]. |
5252 ]. |
5235 ] ifFalse:[ |
5253 |
5236 (doMatch and:[aSelectorString = '*']) ifTrue:[ |
5254 (ignoreCase or:[quickSearch includesMatchCharacters]) ifFalse:[ |
5237 searchBlock := [:class :method :s | true]. |
5255 ^ [:class :methodArg :s | |
|
5256 |method src inLiterals| |
|
5257 |
|
5258 inLiterals := false. |
|
5259 method := methodArg originalMethodIfWrapped. |
|
5260 method isLazyMethod ifTrue:[ |
|
5261 src := method source. |
|
5262 (src notNil and:[src includesString:quickSearch]) ifTrue:[ |
|
5263 method makeRealMethod. |
|
5264 inLiterals := (method |
|
5265 literalsDetect:[:aLiteral| |
|
5266 (aLiteral isMemberOf:Symbol) |
|
5267 and:[(lcString includesString:quickSearch) |
|
5268 and:[(lcString match:aLiteral)]]] |
|
5269 ifNone:nil) notNil |
|
5270 ] |
|
5271 ] ifFalse:[ |
|
5272 inLiterals := (method |
|
5273 literalsDetect:[:aLiteral| |
|
5274 (aLiteral isMemberOf:Symbol) |
|
5275 and:[(lcString includesString:quickSearch) |
|
5276 and:[(lcString match:aLiteral)]]] |
|
5277 ifNone:nil) notNil |
|
5278 ]. |
|
5279 inLiterals and:[ method messagesSent includes:aSelectorString] |
|
5280 ]. |
|
5281 ]. |
|
5282 ^ [:class :methodArg :s | |
|
5283 |method src inLiterals| |
|
5284 |
|
5285 method := methodArg originalMethodIfWrapped. |
|
5286 "/ expensive search |
|
5287 inLiterals := false. |
|
5288 method isLazyMethod ifTrue:[ |
|
5289 src := method source. |
|
5290 (src notNil and:[src includesMatchString:aSelectorString]) ifTrue:[ |
|
5291 method makeRealMethod. |
|
5292 inLiterals := (method |
|
5293 literalsDetect:[:aLiteral| |
|
5294 (aLiteral isMemberOf:Symbol) |
|
5295 and:[(ignoreCase and:[lcString match:aLiteral asLowercase]) |
|
5296 or:[ignoreCase not and:[lcString match:aLiteral]]]] |
|
5297 ifNone:nil) notNil |
|
5298 ] |
|
5299 ] ifFalse:[ |
|
5300 inLiterals := (method literalsDetect:[:aLiteral| |
|
5301 (aLiteral isMemberOf:Symbol) |
|
5302 and:[(ignoreCase and:[lcString match:aLiteral asLowercase]) |
|
5303 or:[ignoreCase not and:[lcString match:aLiteral]]]] |
|
5304 ifNone:nil) notNil |
|
5305 ]. |
|
5306 inLiterals |
|
5307 and:[ |
|
5308 method messagesSent |
|
5309 contains:[:anySelector | aSelectorString match:anySelector caseSensitive:ignoreCase not] |
|
5310 ] |
|
5311 ]. |
|
5312 ]. |
|
5313 |
|
5314 "/ no matchString and not ignoring case - can do it much faster |
|
5315 sel := aSelectorString asSymbolIfInterned. |
|
5316 sel isNil ifTrue:[ |
|
5317 ^ nil "/ none |
|
5318 ]. |
|
5319 |
|
5320 quickSearch := sel. |
|
5321 (quickSearch includes:$:) ifTrue:[ |
|
5322 quickSearch := quickSearch copyTo:(quickSearch indexOf:$:)-1. |
|
5323 ]. |
|
5324 |
|
5325 ^ [:class :methodArg :s | |
|
5326 |method src| |
|
5327 |
|
5328 method := methodArg originalMethodIfWrapped. |
|
5329 method isLazyMethod ifTrue:[ |
|
5330 src := method source. |
|
5331 (src notNil and:[src includesString:quickSearch]) ifTrue:[ |
|
5332 method makeRealMethod. |
|
5333 method referencesLiteral: "sends:" sel. |
|
5334 ] ifFalse:[ |
|
5335 false |
|
5336 ] |
5238 ] ifFalse:[ |
5337 ] ifFalse:[ |
5239 "/ no matchString - can do it much faster |
5338 method sends:sel |
5240 |
|
5241 sel := aSelectorString asSymbolIfInterned. |
|
5242 sel isNil ifTrue:[ |
|
5243 ^ nil "/ none |
|
5244 ]. |
|
5245 |
|
5246 quickMatch := sel. |
|
5247 (quickMatch includes:$:) ifTrue:[ |
|
5248 quickMatch := quickMatch copyTo:(quickMatch indexOf:$:)-1. |
|
5249 ]. |
|
5250 searchBlock := [:class :methodArg :s | |
|
5251 |method src| |
|
5252 |
|
5253 method := methodArg originalMethodIfWrapped. |
|
5254 method isLazyMethod ifTrue:[ |
|
5255 src := method source. |
|
5256 (src notNil and:[src includesString:quickMatch]) ifTrue:[ |
|
5257 method makeRealMethod. |
|
5258 method referencesLiteral: "sends:" sel. |
|
5259 ] ifFalse:[ |
|
5260 false |
|
5261 ] |
|
5262 ] ifFalse:[ |
|
5263 method sends:sel |
|
5264 ] |
|
5265 ]. |
|
5266 ] |
5339 ] |
5267 ]. |
5340 ]. |
5268 ^ searchBlock |
|
5269 |
5341 |
5270 "Modified: / 28-07-2011 / 10:52:51 / cg" |
5342 "Modified: / 28-07-2011 / 10:52:51 / cg" |
5271 ! |
5343 ! |
5272 |
5344 |
5273 searchBlockForCode:aCodeString in:aCollectionOfClasses isMethod:isMethod |
5345 searchBlockForCode:aCodeString in:aCollectionOfClasses isMethod:isMethod |