|
1 " |
|
2 COPYRIGHT (c) 2006 by eXept Software AG |
|
3 All Rights Reserved |
|
4 |
|
5 This software is furnished under a license and may be used |
|
6 only in accordance with the terms of that license and with the |
|
7 inclusion of the above copyright notice. This software may not |
|
8 be provided or otherwise made available to, or used by, any |
|
9 other person. No title to or ownership of the software is |
|
10 hereby transferred. |
|
11 " |
|
12 'From Smalltalk/X, Version:6.1.2 on 19-08-2010 at 10:16:13 PM' ! |
|
13 |
|
14 "{ Package: 'stx:libbasic' }" |
|
15 |
|
16 Lookup subclass:#NamespaceAwareLookup |
|
17 instanceVariableNames:'' |
|
18 classVariableNames:'Instance' |
|
19 poolDictionaries:'' |
|
20 category:'Kernel-Extensions' |
|
21 ! |
|
22 |
|
23 !NamespaceAwareLookup class methodsFor:'documentation'! |
|
24 |
|
25 copyright |
|
26 " |
|
27 COPYRIGHT (c) 2006 by eXept Software AG |
|
28 All Rights Reserved |
|
29 |
|
30 This software is furnished under a license and may be used |
|
31 only in accordance with the terms of that license and with the |
|
32 inclusion of the above copyright notice. This software may not |
|
33 be provided or otherwise made available to, or used by, any |
|
34 other person. No title to or ownership of the software is |
|
35 hereby transferred. |
|
36 " |
|
37 ! ! |
|
38 |
|
39 !NamespaceAwareLookup class methodsFor:'initialization'! |
|
40 |
|
41 initialize |
|
42 |
|
43 Instance := self basicNew |
|
44 |
|
45 "Created: / 10-07-2010 / 21:12:34 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
46 ! ! |
|
47 |
|
48 !NamespaceAwareLookup class methodsFor:'accessing'! |
|
49 |
|
50 instance |
|
51 |
|
52 ^Instance |
|
53 |
|
54 "Created: / 20-05-2010 / 11:18:20 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
55 "Modified: / 10-07-2010 / 21:12:48 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
56 ! ! |
|
57 |
|
58 !NamespaceAwareLookup class methodsFor:'lookup'! |
|
59 |
|
60 lookupMethodForSelector: selector directedTo: initialSearchClass for: receiver withArguments: argArrayOrNil from: sendingContext |
|
61 |
|
62 "JV @ 2010-07-24 |
|
63 Following C code is just a performance optimization. |
|
64 It is not neccessary, however it speeds things in most |
|
65 cases. Such optimization significantly speeds up the IDE |
|
66 since class browser involves dozens of super-polymorphic |
|
67 sends (> 1000 receiver classes per send-site). |
|
68 " |
|
69 |
|
70 %{ |
|
71 OBJ sendingMthd = __ContextInstPtr(sendingContext)->c_method; |
|
72 if (__Class(sendingMthd) == Method && |
|
73 __MethodInstPtr(sendingMthd)->m_annotation == nil) { |
|
74 OBJ m = __lookup(initialSearchClass, selector); |
|
75 if (m != nil) RETURN ( m ); |
|
76 } |
|
77 %}. |
|
78 |
|
79 ^Instance lookupMethodForSelector: selector directedTo: initialSearchClass |
|
80 for: receiver withArguments: argArrayOrNil |
|
81 from: sendingContext |
|
82 |
|
83 ! ! |
|
84 |
|
85 !NamespaceAwareLookup methodsFor:'lookup'! |
|
86 |
|
87 lookupMethodForSelector: selector directedTo: initialSearchClass for: receiver withArguments: argArrayOrNil from: sendingContext |
|
88 "Invoked by the VM to ask me for a method to fire. |
|
89 For details, see comment inLookup>>lookupMethodForSelector:directedTo:for:withArguments:from:" |
|
90 |
|
91 | sendingNs sendingMthd queue seen namespaces methods imports | |
|
92 |
|
93 "JV @ 2010-07-24 |
|
94 Following C code is just a performance optimization. |
|
95 It is not neccessary, however it speeds things in most |
|
96 cases. Such optimization significantly speeds up the IDE |
|
97 since class browser involves dozens of super-polymorphic |
|
98 sends (> 1000 receiver classes per send-site). |
|
99 " |
|
100 %{ |
|
101 sendingMthd = __ContextInstPtr(sendingContext)->c_method; |
|
102 if (__Class(sendingMthd) == Method && |
|
103 __MethodInstPtr(sendingMthd)->m_annotation == nil) { |
|
104 OBJ m = __lookup(initialSearchClass, selector); |
|
105 if (m != nil) RETURN ( m ); |
|
106 } |
|
107 %}. |
|
108 "If you remove C code above, uncomment the line below." |
|
109 "sendingMthd := sendingContext method." |
|
110 sendingNs := sendingMthd isNil |
|
111 ifTrue:[nil] |
|
112 ifFalse:[sendingMthd nameSpace]. |
|
113 sendingNs := sendingNs. |
|
114 |
|
115 "Second chance to speed up things (in case sending method |
|
116 has resource or so)" |
|
117 %{ |
|
118 if (sendingNs == nil) { |
|
119 OBJ m = __lookup(initialSearchClass, selector); |
|
120 if (m != nil) RETURN ( m ); |
|
121 } |
|
122 %}. |
|
123 " |
|
124 Stderr |
|
125 show: 'sel='; show: selector; show: ' ns='; show: sendingNs printString; |
|
126 show: ' method=', sendingMthd printString; cr. |
|
127 " |
|
128 |
|
129 sendingNs notNil ifTrue: [ |
|
130 |
|
131 seen := Set new. |
|
132 namespaces := Array with: sendingNs. |
|
133 |
|
134 [namespaces notEmpty] whileTrue: |
|
135 [ |
|
136 methods := self |
|
137 lookupMethodsForSelector: selector |
|
138 directedTo: initialSearchClass |
|
139 inNamespaces: namespaces. |
|
140 methods size == 1 ifTrue: |
|
141 [^methods anyOne]. |
|
142 methods size > 1 ifTrue: |
|
143 [^self ambiguousMessageSend: selector |
|
144 withArgs: argArrayOrNil]. |
|
145 "No method found" |
|
146 seen addAll: namespaces. |
|
147 imports := Set new. |
|
148 namespaces do: |
|
149 [:namespace| |
|
150 namespace notNil ifTrue: |
|
151 [namespace imports do: |
|
152 [:import| |
|
153 (seen includes: import) ifFalse: |
|
154 [imports add: import]]]]. |
|
155 namespaces := imports]. |
|
156 ]. |
|
157 |
|
158 methods := self lookupMethodsForSelector: selector |
|
159 directedTo: initialSearchClass. |
|
160 methods size == 1 ifTrue:[^methods anyOne]. |
|
161 |
|
162 ^nil |
|
163 |
|
164 "Modified: / 21-07-2010 / 17:11:07 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
165 ! ! |
|
166 |
|
167 !NamespaceAwareLookup methodsFor:'lookup - helpers'! |
|
168 |
|
169 lookupMethodsForSelector: selector directedTo: initialSearchClass |
|
170 |
|
171 "Searches initialSearchClass for a methods with in any namespace" |
|
172 ^self |
|
173 lookupMethodsForSelector: selector |
|
174 directedTo: initialSearchClass |
|
175 suchThat:[:sel :mthd|true]. |
|
176 |
|
177 "Created: / 19-07-2010 / 15:37:06 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
178 ! |
|
179 |
|
180 lookupMethodsForSelector: selector directedTo: initialSearchClass inNamespaces: namespaces |
|
181 |
|
182 "Searches initialSearchClass for a methods with given selector in given namespaces." |
|
183 ^self |
|
184 lookupMethodsForSelector: selector |
|
185 directedTo: initialSearchClass |
|
186 suchThat:[:sel :mthd|namespaces includes: mthd nameSpace]. |
|
187 |
|
188 "Created: / 19-07-2010 / 15:13:59 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
189 ! |
|
190 |
|
191 lookupMethodsForSelector: selector directedTo: initialSearchClass suchThat: block |
|
192 |
|
193 "Searches initialSearchClass for a method with given selector in given nameSpace. |
|
194 if no method in given namespace is found, returns nil" |
|
195 |
|
196 | searchClass methods seen | |
|
197 |
|
198 searchClass := initialSearchClass. |
|
199 methods := Set new. |
|
200 seen := OrderedCollection new. |
|
201 [ searchClass notNil ] whileTrue: |
|
202 [searchClass selectorsAndMethodsDo: |
|
203 [:sel :mthd| |
|
204 (sel selector = selector |
|
205 and:[(seen includes: mthd nameSpace) not |
|
206 and:[block value: sel value: mthd]]) ifTrue: |
|
207 [methods add: mthd. |
|
208 seen add: mthd nameSpace]]. |
|
209 searchClass := searchClass superclass]. |
|
210 ^methods |
|
211 |
|
212 "Created: / 19-07-2010 / 15:34:10 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
213 "Modified: / 20-07-2010 / 10:42:52 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
214 ! ! |
|
215 |
|
216 !NamespaceAwareLookup methodsFor:'trampolines'! |
|
217 |
|
218 ambiguousMessageSend |
|
219 |
|
220 ^self ambiguousMessage: |
|
221 (Message |
|
222 selector: #__placeholder__ |
|
223 arguments: #() |
|
224 ) |
|
225 |
|
226 "Created: / 19-08-2010 / 22:05:48 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
227 ! |
|
228 |
|
229 ambiguousMessageSend: selector withArgs: argArrayOrNil |
|
230 |
|
231 | trampoline | |
|
232 |
|
233 trampoline := self class methodDictionary at: |
|
234 (#(" 0"ambiguousMessageSend |
|
235 " 1"ambiguousMessageSendWith: |
|
236 " 2"ambiguousMessageSendWith:with: |
|
237 " 3"ambiguousMessageSendWith:with:with: |
|
238 " 4"ambiguousMessageSendWith:with:with:with: |
|
239 " 5"ambiguousMessageSendWith:with:with:with:with: |
|
240 " 6"ambiguousMessageSendWith:with:with:with:with:with: |
|
241 " 7"ambiguousMessageSendWith:with:with:with:with:with:with: |
|
242 " 8"ambiguousMessageSendWith:with:with:with:with:with:with:with: |
|
243 ) |
|
244 at: argArrayOrNil size + 1). |
|
245 trampoline := trampoline asByteCodeMethod. |
|
246 1 to: trampoline numLiterals do: |
|
247 [:litNr| |
|
248 (trampoline literalAt: litNr) == #__placeholder__ |
|
249 ifTrue:[(trampoline literalAt: litNr put: selector)]]. |
|
250 ^trampoline |
|
251 |
|
252 "Created: / 19-08-2010 / 22:09:24 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
253 ! |
|
254 |
|
255 ambiguousMessageSendWith: a1 |
|
256 |
|
257 ^self ambiguousMessage: |
|
258 (Message |
|
259 selector: #__placeholder__ |
|
260 arguments: (Array with: a1) |
|
261 ) |
|
262 |
|
263 "Created: / 19-08-2010 / 22:06:08 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
264 ! |
|
265 |
|
266 ambiguousMessageSendWith: a1 with: a2 |
|
267 |
|
268 ^self ambiguousMessage: |
|
269 (Message |
|
270 selector: #__placeholder__ |
|
271 arguments: (Array with: a1 with: a2) |
|
272 ) |
|
273 |
|
274 "Created: / 19-08-2010 / 22:06:37 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
275 ! |
|
276 |
|
277 ambiguousMessageSendWith: a1 with: a2 with: a3 |
|
278 |
|
279 ^self ambiguousMessage: |
|
280 (Message |
|
281 selector: #__placeholder__ |
|
282 arguments: (Array with: a1 with: a2 with: a3) |
|
283 ) |
|
284 |
|
285 "Created: / 19-08-2010 / 22:06:48 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
286 ! |
|
287 |
|
288 ambiguousMessageSendWith: a1 with: a2 with: a3 with: a4 |
|
289 |
|
290 ^self ambiguousMessage: |
|
291 (Message |
|
292 selector: #__placeholder__ |
|
293 arguments: (Array with: a1 with: a2 with: a3 with: a4) |
|
294 ) |
|
295 |
|
296 "Created: / 19-08-2010 / 22:06:56 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
297 ! |
|
298 |
|
299 ambiguousMessageSendWith: a1 with: a2 with: a3 with: a4 |
|
300 with: a5 |
|
301 |
|
302 ^self ambiguousMessage: |
|
303 (Message |
|
304 selector: #__placeholder__ |
|
305 arguments: (Array with: a1 with: a2 with: a3 with: a4 |
|
306 with: a5) |
|
307 ) |
|
308 |
|
309 "Created: / 19-08-2010 / 22:07:15 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
310 ! |
|
311 |
|
312 ambiguousMessageSendWith: a1 with: a2 with: a3 with: a4 |
|
313 with: a5 with: a6 |
|
314 |
|
315 ^self ambiguousMessage: |
|
316 (Message |
|
317 selector: #__placeholder__ |
|
318 arguments: (Array with: a1 with: a2 with: a3 with: a4 |
|
319 with: a5 with: a6) |
|
320 ) |
|
321 |
|
322 "Created: / 19-08-2010 / 22:07:23 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
323 ! |
|
324 |
|
325 ambiguousMessageSendWith: a1 with: a2 with: a3 with: a4 |
|
326 with: a5 with: a6 with: a7 |
|
327 |
|
328 ^self ambiguousMessage: |
|
329 (Message |
|
330 selector: #__placeholder__ |
|
331 arguments: (Array with: a1 with: a2 with: a3 with: a4 |
|
332 with: a5 with: a6 with: a7) |
|
333 ) |
|
334 |
|
335 "Created: / 19-08-2010 / 22:07:37 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
336 ! |
|
337 |
|
338 ambiguousMessageSendWith: a1 with: a2 with: a3 with: a4 |
|
339 with: a5 with: a6 with: a7 with: a8 |
|
340 |
|
341 ^self ambiguousMessage: |
|
342 (Message |
|
343 selector: #__placeholder__ |
|
344 arguments: (Array with: a1 with: a2 with: a3 with: a4 |
|
345 with: a5 with: a6 with: a7 with: a8) |
|
346 ) |
|
347 |
|
348 "Created: / 19-08-2010 / 22:08:03 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
349 ! ! |
|
350 |
|
351 !NamespaceAwareLookup class methodsFor:'documentation'! |
|
352 |
|
353 version_SVN |
|
354 ^ '$Id: NamespaceAwareLookup.st,v 1.1 2011-06-28 11:04:04 vrany Exp $' |
|
355 ! ! |
|
356 |
|
357 NamespaceAwareLookup initialize! |