NamespaceAwareLookup.st
changeset 13403 9cdd42752750
child 13478 0212bdc3f19c
equal deleted inserted replaced
13402:2d18a79f3fcc 13403:9cdd42752750
       
     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!