DoWhatIMeanSupport.st
changeset 5613 46c0f7f9b92c
parent 5612 e77a2fa2031f
child 5621 bc187db92ab4
equal deleted inserted replaced
5612:e77a2fa2031f 5613:46c0f7f9b92c
  1967 !
  1967 !
  1968 
  1968 
  1969 codeCompletionForMessage:node into:actionBlock
  1969 codeCompletionForMessage:node into:actionBlock
  1970     "find good completions for a message selector in a message-send node"
  1970     "find good completions for a message selector in a message-send node"
  1971     
  1971     
  1972     |selector lcSelector bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs
  1972     |selector lcSelector selectorWithoutColon lcSelectorWithoutColon
       
  1973      bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs
  1973      newParts nSelParts oldLen newLen selectorParts
  1974      newParts nSelParts oldLen newLen selectorParts
  1974      parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass
  1975      parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass
  1975      editAction parentNodeClassIfKnown
  1976      editAction parentNodeClassIfKnown
  1976      receiverNodeClassIfKnown 
  1977      receiverNodeClassIfKnown 
  1977      offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
  1978      offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
  1987     offerParenthisationAroundNode := nil.
  1988     offerParenthisationAroundNode := nil.
  1988     offerValueInsertion := false.
  1989     offerValueInsertion := false.
  1989  
  1990  
  1990     selector := node selector.
  1991     selector := node selector.
  1991     lcSelector := selector asLowercase.
  1992     lcSelector := selector asLowercase.
       
  1993 
       
  1994     selectorWithoutColon := selector.
       
  1995     lcSelectorWithoutColon := lcSelector.
       
  1996     (selectorWithoutColon includes:$:) ifTrue:[
       
  1997         selectorWithoutColon := selector upTo:$:.
       
  1998     ].    
       
  1999     (lcSelectorWithoutColon includes:$:) ifTrue:[
       
  2000         lcSelectorWithoutColon := lcSelector upTo:$:.
       
  2001     ].    
       
  2002         
  1992     parentNode := node parent.
  2003     parentNode := node parent.
  1993     nodeReceiver := node receiver.
  2004     nodeReceiver := node receiver.
  1994     nodeReceiver notNil ifTrue:[
  2005     nodeReceiver notNil ifTrue:[
  1995         classesOfReceiver := self classesOfNode:nodeReceiver.
  2006         classesOfReceiver := self classesOfNode:nodeReceiver.
  1996     ].
  2007     ].
  2085                         Parser findBest:30 selectorsFor:selector in:eachClass forCompletion:true.
  2096                         Parser findBest:30 selectorsFor:selector in:eachClass forCompletion:true.
  2086                     ] as:Set) asOrderedCollection.
  2097                     ] as:Set) asOrderedCollection.
  2087  
  2098  
  2088             "/ if any of those is a prefix-keyword of the selector,
  2099             "/ if any of those is a prefix-keyword of the selector,
  2089             "/ do not offer it (i.e. ifTrue:ifFalse: is already present, don't offer ifTrue:ifFalse: again.
  2100             "/ do not offer it (i.e. ifTrue:ifFalse: is already present, don't offer ifTrue:ifFalse: again.
  2090             bestSelectors := bestSelectors reject: [:sel | (selector startsWith: sel) or: [selector endsWith: sel]].
  2101             bestSelectors := bestSelectors reject: [:sel | 
       
  2102                                 (selector startsWith: sel) or: [selector endsWith: sel]
       
  2103                              ].
  2091         ].
  2104         ].
  2092     ].                                                                            
  2105     ].                                                                            
  2093  
  2106  
  2094     "/ if we are behind a keyword messages colon,
  2107     "/ if we are behind a keyword messages colon,
  2095     "/ only look for matching prefix selectors;
  2108     "/ only look for matching prefix selectors;
  2101             offerParenthisationAroundNode := node. 
  2114             offerParenthisationAroundNode := node. 
  2102             "/ Transcript show:'2:'; showCR:node.
  2115             "/ Transcript show:'2:'; showCR:node.
  2103         ].
  2116         ].
  2104  
  2117  
  2105         codeView characterBeforeCursor == $: ifTrue:[
  2118         codeView characterBeforeCursor == $: ifTrue:[
  2106             (bestSelectors select:[:sel | sel asLowercase startsWith:lcSelector]) isEmpty ifTrue:[
  2119             (bestSelectors select:[:sel | sel asLowercase startsWith:lcSelectorWithoutColon]) isEmpty ifTrue:[
  2107                 "/ nothing better around
  2120                 "/ nothing better around
  2108                 |argIndex argNames argNameStrings impls|
  2121                 |argIndex argNames argNameStrings impls|
  2109  
  2122  
  2110                 argIndex := node selectorParts size.
  2123                 argIndex := node selectorParts size.
  2111                 argNames := Set new.
  2124                 argNames := Set new.
  2136         "/ when completing a non-keyword AND the parent is a keyword message,
  2149         "/ when completing a non-keyword AND the parent is a keyword message,
  2137         "/ only consider longer keyword messages or unary messages.
  2150         "/ only consider longer keyword messages or unary messages.
  2138         "/ unless the node is parenthesized
  2151         "/ unless the node is parenthesized
  2139         node hasParentheses ifFalse:[ 
  2152         node hasParentheses ifFalse:[ 
  2140             (parentNode notNil and:[ parentNode isKeywordMessage ]) ifTrue:[
  2153             (parentNode notNil and:[ parentNode isKeywordMessage ]) ifTrue:[
  2141                 bestSelectors := bestSelectors select:[:sel | sel isUnarySelector or:[ sel startsWith:sel]]
  2154                 bestSelectors := bestSelectors select:[:sel |
       
  2155                                     sel isUnarySelector 
       
  2156                                     or:[ sel startsWith:parentNode selector]
       
  2157                                  ]
  2142             ]
  2158             ]
  2143         ]
  2159         ]
  2144     ].
  2160     ].
  2145  
  2161  
  2146 "/    bestSelectors := bestSelectors asOrderedCollection.
  2162 "/    bestSelectors := bestSelectors asOrderedCollection.
  2321             ].
  2337             ].
  2322         ].
  2338         ].
  2323     ].
  2339     ].
  2324  
  2340  
  2325     allBest := (bestSelectors ? #()) , (bestSelectors2 ? #()) asOrderedCollection.
  2341     allBest := (bestSelectors ? #()) , (bestSelectors2 ? #()) asOrderedCollection.
  2326     self sortSelectors:allBest forSelector:selector lcSelector:lcSelector.
  2342     self sortSelectors:allBest forSelector:selectorWithoutColon lcSelector:lcSelectorWithoutColon.
  2327                         
  2343                         
  2328     "/ sort: prefixes first.
  2344     "/ sort: prefixes first.
  2329     parentSelector notNil ifTrue:[
  2345     parentSelector notNil ifTrue:[
  2330         allBest := self 
  2346         allBest := self 
  2331                     splitSelectorList:allBest 
  2347                     splitSelectorList:allBest 
  2332                     by:[:sel | 
  2348                     by:[:sel | 
  2333                             (sel asLowercase startsWith:lcSelector) 
  2349                             (sel asLowercase startsWith:lcSelectorWithoutColon) 
  2334                             or:[sel startsWith:parentSelector]].
  2350                             or:[sel startsWith:parentSelector]].
  2335     ].
  2351     ].
  2336  
  2352  
  2337     "/ if receiver is super, always include the method's own selector
  2353     "/ if receiver is super, always include the method's own selector
  2338     nodeReceiver isSuper ifTrue:[
  2354     nodeReceiver isSuper ifTrue:[
  2339         (tree isMethod) ifTrue:[
  2355         (tree isMethod) ifTrue:[
  2340             |mSel|
  2356             |mSel|
  2341  
  2357  
  2342             mSel := tree selector.
  2358             mSel := tree selector.
  2343             mSel notNil ifTrue:[
  2359             mSel notNil ifTrue:[
  2344                 (mSel startsWith:selector) ifTrue:[
  2360                 (mSel startsWith:selectorWithoutColon) ifTrue:[
  2345                     "/ already the word before the cursor?
  2361                     "/ already the word before the cursor?
  2346                     (mSel ~= selector) ifTrue:[
  2362                     (mSel ~= selector) ifTrue:[
  2347                         allBest removeAndAddFirst:mSel.
  2363                         allBest removeAndAddFirst:mSel.
  2348                     ]
  2364                     ]
  2349                 ]
  2365                 ]
  2477 "/].
  2493 "/].
  2478  
  2494  
  2479     (parentSelector notNil and:[parentSelector includes:$:]) ifTrue:[
  2495     (parentSelector notNil and:[parentSelector includes:$:]) ifTrue:[
  2480         "/ the one's which are a prefix are moved towards the top of the list
  2496         "/ the one's which are a prefix are moved towards the top of the list
  2481         allBest := self splitSelectorList:allBest 
  2497         allBest := self splitSelectorList:allBest 
  2482                         by:[:sel | sel notNil and:[sel asLowercase startsWith:lcSelector]].
  2498                         by:[:sel | sel notNil and:[sel asLowercase startsWith:lcSelectorWithoutColon]].
  2483     ].
  2499     ].
  2484     
  2500     
  2485     "/ heuristic hack:
  2501     "/ heuristic hack:
  2486     "/ 'i' and 'w' generate lists in which ifXXX / whileXXX are not at the top of the list.
  2502     "/ 'i' and 'w' generate lists in which ifXXX / whileXXX are not at the top of the list.
  2487     "/ we know, that those are most often wanted!!
  2503     "/ we know, that those are most often wanted!!
  2492                         #(ifTrue: ifFalse: isNil notNil whileTrue whileFalse) includes:sel
  2508                         #(ifTrue: ifFalse: isNil notNil whileTrue whileFalse) includes:sel
  2493                     ].
  2509                     ].
  2494     ]. 
  2510     ]. 
  2495 
  2511 
  2496     "/ sort again: prefixes must always come before
  2512     "/ sort again: prefixes must always come before
  2497     self sortSelectors:allBest forSelector:selector lcSelector:lcSelector.
  2513     allBest sortBySelector:#size.
  2498     self sortUsefulSelectorsIn:allBest. "/cosmetics
  2514     self sortSelectors:allBest forSelector:selectorWithoutColon lcSelector:lcSelectorWithoutColon.
       
  2515     "/ self sortUsefulSelectorsIn:allBest. "/cosmetics
  2499 
  2516 
  2500     (parentSelector notNil and:[parentSelector includes:$:]) ifTrue:[
  2517     (parentSelector notNil and:[parentSelector includes:$:]) ifTrue:[
  2501         allBest := (allBest 
  2518         allBest := (allBest 
  2502                         select:[:sel | sel startsWith:parentSelector]
  2519                         select:[:sel | sel startsWith:parentSelector]
  2503                         thenCollect:[:sel | sel copyFrom:(parentSelector lastIndexOf:$:)+1])
  2520                         thenCollect:[:sel | sel copyFrom:(parentSelector lastIndexOf:$:)+1])
  2701         ].
  2718         ].
  2702     actionBlock value:allBest value:editAction value:nil.
  2719     actionBlock value:allBest value:editAction value:nil.
  2703 
  2720 
  2704     "Created: / 10-11-2006 / 13:18:27 / cg"
  2721     "Created: / 10-11-2006 / 13:18:27 / cg"
  2705     "Modified: / 16-02-2010 / 10:33:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2722     "Modified: / 16-02-2010 / 10:33:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2706     "Modified: / 15-09-2017 / 11:07:13 / cg"
  2723     "Modified: / 30-09-2017 / 14:12:47 / cg"
  2707 !
  2724 !
  2708 
  2725 
  2709 codeCompletionForMessageTo:node into:actionBlock
  2726 codeCompletionForMessageTo:node into:actionBlock
  2710     "find good suggestions for a message send to node, with no input yet.
  2727     "find good suggestions for a message send to node, with no input yet.
  2711      I.e. right after a receiver (w.o. any input yet)"
  2728      I.e. right after a receiver (w.o. any input yet)"
  2786 codeCompletionForMethodSpec:node
  2803 codeCompletionForMethodSpec:node
  2787     "completion in a method's selector pattern"
  2804     "completion in a method's selector pattern"
  2788 
  2805 
  2789     self
  2806     self
  2790         codeCompletionForMethodSpec:node
  2807         codeCompletionForMethodSpec:node
  2791         into:
  2808         into:[:suggestions :action :whatIsIt |
  2792             [:suggestions :action :whatIsIt |
       
  2793 
  2809 
  2794             |chosen|
  2810             |chosen|
  2795 
  2811 
  2796             chosen := self askUserForCompletion:whatIsIt for:codeView
  2812             chosen := self askUserForCompletion:whatIsIt for:codeView
  2797                            at:node start from:suggestions.
  2813                            at:node start from:suggestions.
  2908 
  2924 
  2909     "Modified: / 04-07-2006 / 18:48:26 / fm"
  2925     "Modified: / 04-07-2006 / 18:48:26 / fm"
  2910     "Created: / 10-11-2006 / 13:46:44 / cg"
  2926     "Created: / 10-11-2006 / 13:46:44 / cg"
  2911     "Modified: / 16-02-2010 / 10:13:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2927     "Modified: / 16-02-2010 / 10:13:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
  2912     "Modified: / 01-06-2012 / 20:31:36 / cg"
  2928     "Modified: / 01-06-2012 / 20:31:36 / cg"
       
  2929     "Modified (format): / 30-09-2017 / 12:58:32 / cg"
  2913 !
  2930 !
  2914 
  2931 
  2915 codeCompletionForMethodSpec:node into:actionBlock
  2932 codeCompletionForMethodSpec:node into:actionBlock
  2916     "completion in a method's selector pattern"
  2933     "completion in a method's selector pattern"
  2917 
  2934 
  4365 
  4382 
  4366 sortSelectors:list forSelector:selector lcSelector:lcSelector
  4383 sortSelectors:list forSelector:selector lcSelector:lcSelector
  4367     list sort: [:a :b |
  4384     list sort: [:a :b |
  4368         |aBeforeB|
  4385         |aBeforeB|
  4369 
  4386 
       
  4387 "/        (a startsWith:'sho') ifTrue:[
       
  4388 "/            (b startsWith:'sho') ifTrue:[
       
  4389 "/                self halt.
       
  4390 "/            ].
       
  4391 "/        ].
       
  4392         
  4370         (a startsWith:selector) ifTrue:[
  4393         (a startsWith:selector) ifTrue:[
  4371             (b startsWith:selector) ifFalse:[
  4394             (b startsWith:selector) ifTrue:[
       
  4395                 aBeforeB := (a size < b size) or:[a < b]
       
  4396             ] ifFalse:[
  4372                 aBeforeB := true
  4397                 aBeforeB := true
  4373             ]
  4398             ] 
  4374         ] ifFalse:[    
  4399         ] ifFalse:[    
  4375             (b startsWith:selector) ifTrue:[
  4400             (b startsWith:selector) ifTrue:[
  4376                 aBeforeB := false
  4401                 aBeforeB := false
  4377             ]
  4402             ]
  4378         ].
  4403         ].
  4388                 ]
  4413                 ]
  4389             ].
  4414             ].
  4390         ].
  4415         ].
  4391         aBeforeB
  4416         aBeforeB
  4392     ].
  4417     ].
       
  4418 
       
  4419     "Modified: / 30-09-2017 / 14:10:06 / cg"
  4393 !
  4420 !
  4394 
  4421 
  4395 sortUsefulSelectorsIn:selectorList
  4422 sortUsefulSelectorsIn:selectorList
  4396     "/ cosmetics: 
  4423     "/ cosmetics: 
  4397     "/  ifTrue / whileTrue should come before ifFalse/whileFalse
  4424     "/  ifTrue / whileTrue should come before ifFalse/whileFalse