DoWhatIMeanSupport.st
changeset 5112 a25d288252f4
parent 5109 18c01df208c2
child 5113 6a5ae22ee501
equal deleted inserted replaced
5111:ce09771c85a9 5112:a25d288252f4
  1868 codeCompletionForMessage:node into:actionBlock
  1868 codeCompletionForMessage:node into:actionBlock
  1869     "find good completions for a message selector in a message-send node"
  1869     "find good completions for a message selector in a message-send node"
  1870     
  1870     
  1871     |selector lcSelector bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs
  1871     |selector lcSelector bestSelectors parentSelector newParentSelector bestSelectors2 bestWithParenthesis allBest numArgs
  1872      newParts nSelParts oldLen newLen selectorParts
  1872      newParts nSelParts oldLen newLen selectorParts
  1873      findBest parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass
  1873      parentNode nodeReceiver "selectorsSentInCode" selectorsImplementedInClass
  1874      editAction parentNodeClassIfKnown
  1874      editAction parentNodeClassIfKnown
  1875      receiverNodeClassIfKnown 
  1875      receiverNodeClassIfKnown 
  1876      offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
  1876      offerParenthisationAroundNode parenthesisAroundIndex parentNodeToParenthesize
  1877      offerValueInsertion valueToInsert valueToInsertIndex valueInfo
  1877      offerValueInsertion valueToInsert valueToInsertIndex valueInfo
  1878      classesFromAssignmentsToReceiver otherMessagesToReceiver
  1878      classesFromAssignmentsToReceiver otherMessagesToReceiver
  1879      canParenthesize classesOfReceiver|
  1879      canParenthesize classesOfReceiver|
  1880  
  1880  
  1881     "/ Transcript show:'node '; show:node; show:' ; '.
  1881     Verbose == true ifTrue:[
  1882     "/ Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil.
  1882         Transcript show:'node '; show:node; show:' ; '.
  1883  
  1883         Transcript show:'msg in '; show:methodOrNil; show:' / '; showCR:classOrNil.
       
  1884     ].
       
  1885     
  1884     offerParenthisationAroundNode := nil.
  1886     offerParenthisationAroundNode := nil.
  1885     offerValueInsertion := false.
  1887     offerValueInsertion := false.
  1886  
       
  1887     "/ node at:1
       
  1888  
       
  1889     findBest := 
       
  1890         [:node :selector |
       
  1891             |srchClasses bestSelectors bestPrefixes
       
  1892              allMessagesSentToVariable classesImplementingAllMessages|
       
  1893 
       
  1894             srchClasses := node==nodeReceiver 
       
  1895                             ifTrue:[classesOfReceiver]
       
  1896                             ifFalse:[self classesOfNode:node].
       
  1897  
       
  1898             srchClasses isEmptyOrNil ifTrue:[
       
  1899                 node isVariable ifTrue:[
       
  1900                     allMessagesSentToVariable := Set new.
       
  1901                     rememberedNodes do:[:eachNode |
       
  1902                         eachNode allMessageNodesDo:[:eachMessage |
       
  1903                             |msgReceiver msgSelector|
       
  1904                             
       
  1905                             (msgReceiver := eachMessage receiver) isVariable ifTrue:[
       
  1906                                 msgReceiver name = node name ifTrue:[
       
  1907                                     (msgSelector := eachMessage selector) ~= selector ifTrue:[
       
  1908                                         allMessagesSentToVariable add:msgSelector
       
  1909                                     ]
       
  1910                                 ]
       
  1911                             ]
       
  1912                         ]
       
  1913                     ].
       
  1914                     allMessagesSentToVariable notEmpty ifTrue:[
       
  1915                         "/ consider classes which implement all those messages.
       
  1916                         classesImplementingAllMessages := Smalltalk allImplementorsOf:(allMessagesSentToVariable first).
       
  1917                         allMessagesSentToVariable do:[:eachSelector |
       
  1918                             classesImplementingAllMessages := classesImplementingAllMessages
       
  1919                                                                 select:[:cls | cls implements:eachSelector].
       
  1920                         ].
       
  1921                         srchClasses := classesImplementingAllMessages.
       
  1922                     ].
       
  1923                 ].
       
  1924             ].
       
  1925             bestSelectors := Set new.
       
  1926             srchClasses isEmptyOrNil ifTrue:[
       
  1927                 bestSelectors addAll:( Parser findBest:50 selectorsFor:selector in:nil forCompletion:true ).
       
  1928             ] ifFalse:[    
       
  1929                 srchClasses do:[:srchClass |
       
  1930                     |bestForThisClass|
       
  1931  
       
  1932                     bestForThisClass := Parser findBest:50 selectorsFor:selector in:srchClass forCompletion:true.
       
  1933                     bestForThisClass := self
       
  1934                                         withoutSelectorsUnlikelyFor:srchClass
       
  1935                                         from:bestForThisClass
       
  1936                                         forPartial:selector.
       
  1937                     bestSelectors addAll:bestForThisClass.
       
  1938                 ].
       
  1939             ].
       
  1940             "/ remove the already typed-in selector itself, in case.
       
  1941             bestSelectors remove:selector ifAbsent:[].
       
  1942             bestSelectors := bestSelectors asOrderedCollection.
       
  1943             bestSelectors
       
  1944         ].
       
  1945  
  1888  
  1946     selector := node selector.
  1889     selector := node selector.
  1947     lcSelector := selector asLowercase.
  1890     lcSelector := selector asLowercase.
  1948     parentNode := node parent.
  1891     parentNode := node parent.
  1949     nodeReceiver := node receiver.
  1892     nodeReceiver := node receiver.
  1950     nodeReceiver notNil ifTrue:[
  1893     nodeReceiver notNil ifTrue:[
  1951         classesOfReceiver := self classesOfNode:nodeReceiver.
  1894         classesOfReceiver := self classesOfNode:nodeReceiver.
  1952     ].
  1895     ].
  1953 Transcript show:node; show:' -> '; showCR:classesOfReceiver.
  1896     Verbose == true ifTrue:[
  1954 ( node isVariable and:[node name = 'self']) ifTrue:[self halt].
  1897         Transcript show:node; show:' -> '; showCR:classesOfReceiver.
  1955 
  1898         ( node isVariable and:[node name = 'self']) ifTrue:[self halt].
       
  1899     ].
       
  1900     
  1956     "/ if there is already space before the cursor, and the parent node is not a message,
  1901     "/ if there is already space before the cursor, and the parent node is not a message,
  1957     "/ do not attempt to complete the current message.
  1902     "/ do not attempt to complete the current message.
  1958     "/ If it is a message, we will look for parent-message completion also below (best2 stuff)
  1903     "/ If it is a message, we will look for parent-message completion also below (best2 stuff)
  1959     (codeView characterBeforeCursor ? $ ) isSeparator ifTrue:[
  1904     (codeView characterBeforeCursor ? $ ) isSeparator ifTrue:[
  1960         selector isKeyword ifFalse:[
  1905         selector isKeyword ifFalse:[
  1963         ].
  1908         ].
  1964     ].
  1909     ].
  1965  
  1910  
  1966     "/ only do this if the node-message has no parents around
  1911     "/ only do this if the node-message has no parents around
  1967     node parentheses isEmptyOrNil ifTrue:[
  1912     node parentheses isEmptyOrNil ifTrue:[
  1968         bestSelectors := findBest value:nodeReceiver value:selector.
  1913         Verbose == true ifTrue:[
       
  1914             Transcript show:'try for: '; showCR:nodeReceiver
       
  1915         ].    
       
  1916         bestSelectors := self findBest:nodeReceiver for:selector 
       
  1917                               inClasses:classesOfReceiver
  1969     ] ifFalse:[
  1918     ] ifFalse:[
  1970         bestSelectors := OrderedCollection new.
  1919         bestSelectors := OrderedCollection new.
  1971     ].
  1920     ].
  1972  
  1921  
  1973     "/ if the receiver is a real variable,
  1922     "/ if the receiver is a real variable,
  2095     (selector isUnarySelector and:[ parentNode notNil and:[ parentNode isMessage ]]) ifTrue:[
  2044     (selector isUnarySelector and:[ parentNode notNil and:[ parentNode isMessage ]]) ifTrue:[
  2096         (parentSelector := parentNode selector) isKeyword ifTrue:[
  2045         (parentSelector := parentNode selector) isKeyword ifTrue:[
  2097             "/ if its a unary message AND the parent is a keyword node, look for parent completion too.
  2046             "/ if its a unary message AND the parent is a keyword node, look for parent completion too.
  2098             "/ i.e. look if there is a longer keyword possible
  2047             "/ i.e. look if there is a longer keyword possible
  2099             newParentSelector := parentSelector,selector.
  2048             newParentSelector := parentSelector,selector.
  2100             bestSelectors2 := findBest value:(parentNode receiver) value:newParentSelector.
  2049             bestSelectors2 := self 
       
  2050                                 findBest:(parentNode receiver) for:newParentSelector 
       
  2051                                 inClasses:(self classesOfNode:parentNode receiver).
  2101             bestSelectors2 := bestSelectors2 select:[:sel | sel isKeyword and:[ sel startsWith:parentSelector]].
  2052             bestSelectors2 := bestSelectors2 select:[:sel | sel isKeyword and:[ sel startsWith:parentSelector]].
  2102             bestSelectors2 := bestSelectors2 asOrderedCollection sort:[:a :b | a size < b size].
  2053             bestSelectors2 := bestSelectors2 asOrderedCollection sort:[:a :b | a size < b size].
  2103             bestSelectors := bestSelectors reject:[:sel | bestSelectors2 includes:sel].
  2054             bestSelectors := bestSelectors reject:[:sel | bestSelectors2 includes:sel].
  2104  
  2055  
  2105             "/ if the parent has a valid selector, offer parenthization
  2056             "/ if the parent has a valid selector, offer parenthization
  2143             "/    or after foo bar baz <-
  2094             "/    or after foo bar baz <-
  2144             "/ not if typing into an existing message
  2095             "/ not if typing into an existing message
  2145             "/ (i.e. into foo == shift <- more
  2096             "/ (i.e. into foo == shift <- more
  2146             "/    or into foo bar <- baz
  2097             "/    or into foo bar <- baz
  2147             codeView characterPositionOfCursor >= parentNode stop ifTrue:[
  2098             codeView characterPositionOfCursor >= parentNode stop ifTrue:[
  2148                 kwSels := findBest value:parentNode value:selector.
  2099                 kwSels := self 
       
  2100                                 findBest:parentNode for:selector 
       
  2101                                 inClasses:(self classesOfNode:parentNode).
  2149                 kwSels := kwSels select:[:sel | sel isKeyword].
  2102                 kwSels := kwSels select:[:sel | sel isKeyword].
  2150      
  2103      
  2151                 kwSels := kwSels asOrderedCollection sort:[:a :b | a size < b size].
  2104                 kwSels := kwSels asOrderedCollection sort:[:a :b | a size < b size].
  2152  
  2105  
  2153                 bestSelectors := bestSelectors reject:[:sel | kwSels includes:sel].
  2106                 bestSelectors := bestSelectors reject:[:sel | kwSels includes:sel].
  3772     ^ self editActionToReplaceCodeFrom:node start to:node stop byWordIn:suggestions
  3725     ^ self editActionToReplaceCodeFrom:node start to:node stop byWordIn:suggestions
  3773 
  3726 
  3774     "Created: / 01-05-2016 / 18:44:09 / cg"
  3727     "Created: / 01-05-2016 / 18:44:09 / cg"
  3775 !
  3728 !
  3776 
  3729 
       
  3730 findBest:node for:selector inClasses:srchClassesArg
       
  3731     |srchClasses bestSelectors
       
  3732      allMessagesSentToVariable classesImplementingAllMessages|
       
  3733 
       
  3734     srchClasses := srchClassesArg.
       
  3735     Verbose == true ifTrue:[
       
  3736         Transcript show:'node: '; showCR:node.
       
  3737         Transcript show:'srchClasses: '; showCR:srchClasses.
       
  3738     ].
       
  3739     
       
  3740     srchClasses isEmptyOrNil ifTrue:[
       
  3741         node isVariable ifTrue:[
       
  3742             allMessagesSentToVariable := Set new.
       
  3743             rememberedNodes do:[:eachNode |
       
  3744                 eachNode allMessageNodesDo:[:eachMessage |
       
  3745                     |msgReceiver msgSelector|
       
  3746 
       
  3747                     (msgReceiver := eachMessage receiver) isVariable ifTrue:[
       
  3748                         msgReceiver name = node name ifTrue:[
       
  3749                             (msgSelector := eachMessage selector) ~= selector ifTrue:[
       
  3750                                 allMessagesSentToVariable add:msgSelector
       
  3751                             ]
       
  3752                         ]
       
  3753                     ]
       
  3754                 ]
       
  3755             ].
       
  3756             allMessagesSentToVariable notEmpty ifTrue:[
       
  3757                 "/ consider classes which implement all those messages.
       
  3758                 classesImplementingAllMessages := Smalltalk allImplementorsOf:(allMessagesSentToVariable first).
       
  3759                 allMessagesSentToVariable do:[:eachSelector |
       
  3760                     classesImplementingAllMessages := classesImplementingAllMessages
       
  3761                                                         select:[:cls | cls implements:eachSelector].
       
  3762                 ].
       
  3763                 srchClasses := classesImplementingAllMessages.
       
  3764             ].
       
  3765         ].
       
  3766     ].
       
  3767     bestSelectors := Set new.
       
  3768     srchClasses isEmptyOrNil ifTrue:[
       
  3769         bestSelectors addAll:( Parser findBest:50 selectorsFor:selector in:nil forCompletion:true ).
       
  3770         Verbose == true ifTrue:[
       
  3771             Transcript show:'bestSelectors (1): '; showCR:bestSelectors.
       
  3772         ].
       
  3773     ] ifFalse:[    
       
  3774         srchClasses do:[:srchClass |
       
  3775             |bestForThisClass|
       
  3776 
       
  3777             bestForThisClass := Parser findBest:50 selectorsFor:selector in:srchClass forCompletion:true.
       
  3778             bestForThisClass := self
       
  3779                                 withoutSelectorsUnlikelyFor:srchClass
       
  3780                                 from:bestForThisClass
       
  3781                                 forPartial:selector.
       
  3782             Verbose == true ifTrue:[
       
  3783                 Transcript show:'bestSelectors (2): '; showCR:bestForThisClass.
       
  3784             ].
       
  3785             bestSelectors addAll:bestForThisClass.
       
  3786         ].
       
  3787     ].
       
  3788     "/ remove the already typed-in selector itself, in case.
       
  3789     bestSelectors remove:selector ifAbsent:[].
       
  3790     bestSelectors := bestSelectors asOrderedCollection.
       
  3791     ^ bestSelectors
       
  3792 !
       
  3793 
  3777 findNodeForInterval:interval in:source
  3794 findNodeForInterval:interval in:source
  3778     |tree node|
  3795     |tree node|
  3779 
  3796 
  3780     interval isEmpty ifTrue: [^ nil].
  3797     interval isEmpty ifTrue: [^ nil].
  3781     RBParser isNil ifTrue: [^ nil].
  3798     RBParser isNil ifTrue: [^ nil].
  4599      found in object, but only make sense for variable objects or those which do
  4616      found in object, but only make sense for variable objects or those which do
  4600      implement at:put: themself.
  4617      implement at:put: themself.
  4601      I have currently no better idea than hardcoding stuff I found irritating..."
  4618      I have currently no better idea than hardcoding stuff I found irritating..."
  4602 
  4619 
  4603     |selectors noNilChecks noIsXXXChecks noNoXXXChecks noBecome 
  4620     |selectors noNilChecks noIsXXXChecks noNoXXXChecks noBecome 
  4604      noIndexedSetters noIndexedGetters noSizeQueries|
  4621      noIndexedSetters noIndexedGetters noSizeQueries docSelectors|
  4605 
  4622 
  4606     aClass isNil ifTrue:[ ^ selectorsArg ].
  4623     aClass isNil ifTrue:[ ^ selectorsArg ].
  4607 
  4624 
  4608     noNilChecks := noIsXXXChecks := noNoXXXChecks := noBecome := false.
  4625     noNilChecks := noIsXXXChecks := noNoXXXChecks := noBecome := false.
  4609     noIndexedSetters := noIndexedGetters := noSizeQueries := false.
  4626     noIndexedSetters := noIndexedGetters := noSizeQueries := false.
  4610 
  4627 
  4611     selectors := (selectorsArg ? #()) asOrderedCollection.
  4628     selectors := (selectorsArg ? #()) asOrderedCollection.
  4612 
  4629 
  4613     self tracePoint:#cg message:aClass.
  4630     self tracePoint:#cg message:aClass.
  4614 
  4631 
       
  4632     aClass isMeta ifTrue:[
       
  4633         docSelectors := #(copyright documentation examples 
       
  4634                           version version_CVS version_SVN version_HG).
       
  4635         selectors := selectors reject:[:sel | docSelectors includes:sel].
       
  4636     ].
       
  4637     
  4615     "/ actually meaning booleans here
  4638     "/ actually meaning booleans here
  4616     (aClass == True or:[aClass == False]) ifTrue:[
  4639     (aClass == True or:[aClass == False]) ifTrue:[
  4617         noNilChecks := noBecome := true.
  4640         noNilChecks := noBecome := true.
  4618         (partialSelector startsWith:'is') ifFalse:[ noIsXXXChecks := true ].
  4641         (partialSelector startsWith:'is') ifFalse:[ noIsXXXChecks := true ].
  4619         (partialSelector startsWith:'no') ifFalse:[ noNoXXXChecks := true ].
  4642         (partialSelector startsWith:'no') ifFalse:[ noNoXXXChecks := true ].