Search code examples
compilationsmalltalkpharo

Browsing "Senders" in Finder also returns code that doesn't contain the message I'm searching for in Pharo?


Opened a fresh Pharo 5 image, opened Finder and searched for the + selector. Then selected the + and clicked Senders. Got about 5000 results, most of them seem fine, however upon closer inspection some results seem to missing any reference of my message send.

Not a few I might add, about 1700 of them seem to be erroneous and contain no reference of + what so ever. What do you think is the problem? Here's one example:

Example


Solution

  • Update

    The search goes both through the textual source code and the bytecode; so it shows you the method, because it found #+ in the bytecode, but the browser is too limited to show you both text and bytes, so it shows you only the text (even though the match was done on bytecode)

    As for bytecode itself, Pharo (re)compiles a method every time you save it; so for example when you save the following method

    Something>>loop
        1 to: 10 do: [ :each | ]
    

    the system will compile it, and when you inspect the method and look at the bytecode, you will see this

    enter image description here

    You can write the bytecode by hand too I believe.


    Original answer

    Because for some special selectors it also looks through the bytecode, which you can see when you inspect the method itself.

    enter image description here

    This can be very easily discovered in less than a minute by looking through the code of Pharo itself (once you are more comfortable with Pharo):

    • #+ senders gives you the list of senders of a selector,
    • so you look at the implementation of senders and go through the available call chain (you can select selector with mouse or doubleclick and ctrl+n to show you the senders browser)
      • sendersallSendersOf:thoroughWhichSelectorsReferTo:
    • and there you see

    .

    thoroughWhichSelectorsReferTo: literal
        "Answer a set of selectors whose methods access the argument as a 
        literal. Dives into the compact literal notation, making it slow but 
        thorough "
        | selectors special byte |
        "for speed we check the special selectors here once per class"
        special := Smalltalk
            hasSpecialSelector: literal
            ifTrueSetByte: [ :value | byte := value ].
        selectors := OrderedCollection new.
        self selectorsAndMethodsDo: [ :sel :method |
                ((method refersToLiteral: literal) or: [special and: [method scanFor: byte]]) ifTrue: [selectors add: sel]].
        ^ selectors