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 ]. |