GemTalk / Sparkle

MIT License
11 stars 5 forks source link

Highlighting of current step position does not highlight all keywords of selector #50

Open martinmcclure opened 3 years ago

martinmcclure commented 3 years ago

When execution is stopped at a the send of a message with a keyword selector, the Sparkle debugger code currently in martinDebuggerDev branch highlights only the first keyword of the selector.

It would be easier to understand if all the keywords were highlighted.

This would require more thorough parsing of the method source than Sparkle currently does. I hear that Dale has an RBParser working in GemStone, perhaps that could be used for this purpose?

dalehenrich commented 3 years ago

@rjsargent did the original port of RBParser :) ... right now it is part of Rowan and may not be easily stripped out of Rowan (because of dependencies on other methods) ... but once Sparkle is running on top of Rowan, it will be available ...

dalehenrich commented 3 years ago

In tODE I use this method to calculate the selection range in stack frames (ignore the respondsTo: --- easier to do that than create a new package for a single method: --- tODE runs in versions from 2.4 through 3.7):

calculateSelectionRange
    | method stepPoint begin end |
    method := self method.
    (method respondsTo: #'_stepPointForIp:level:isNative:')
        ifTrue: [ 
            stepPoint := method
                perform: #'_stepPointForIp:level:isNative:'
                withArguments:
                    {(self ipOffset).
                    (self frameIndex).
                    (self process _nativeStack)} ]
        ifFalse: [ 
            "v3.3"
            stepPoint := method
                perform: #'_stepPointForIp:level:useNext:'
                withArguments:
                    {(self ipOffset).
                    (self frameIndex).
                    (self process _nativeStack)} ].
    begin := method _sourceOffsetsAt: stepPoint.
    end := self calculateSourceRangeEnd: begin in: method sourceString.
    ^ begin to: end

and

calculateSourceRangeEnd: start in: string
    | scan i char characterStack beginners enders |
    i := start.
    (string at: i) = $^
        ifTrue: [ ^ string size - 1 ].
    (char := string at: i) isCompilerSpecial
        ifTrue: [ 
            ^ (i < string size and: [ (char := string at: i + 1) isCompilerSpecial ])
                ifTrue: [ i + 1 ]
                ifFalse: [ i ] ].
    scan := true.
    [ scan ]
        whileTrue: [ 
            [ i <= string size and: [ (string at: i) isSeparator ] ]
                whileTrue: [ i := i + 1 ].
            [ 
            i <= string size
                and: [ (char := string at: i) isAlphaNumeric or: [ char = $_ ] ] ]
                whileTrue: [ i := i + 1 ].
            char = $:
                ifFalse: [ ^ i - 1 ].
            scan := start == 1.
            scan
                ifTrue: [ i := i + 1 ] ].
    characterStack := OrderedCollection new.
    beginners := String
        with: $'
        with: $"
        with: $(
        with: $[.
    enders := String with: $) with: $].
    [ 
    i := i + 1.
    i < string size ]
        whileTrue: [ 
            char := string at: i.
            characterStack isEmpty
                ifTrue: [ 
                    (char = $. or: [ char = $; ])
                        ifTrue: [ ^ i - 1 ].
                    (beginners includes: char)
                        ifTrue: [ characterStack addLast: char ]
                        ifFalse: [ 
                            (enders includes: char)
                                ifTrue: [ ^ i - 1 ] ] ]
                ifFalse: [ 
                    (characterStack last = $' or: [ characterStack last = $" ])
                        ifTrue: [ 
                            char = characterStack last
                                ifTrue: [ characterStack removeLast ] ]
                        ifFalse: [ 
                            (beginners includes: char)
                                ifTrue: [ characterStack addLast: char ]
                                ifFalse: [ 
                                    (characterStack last = $( and: [ char = $) ])
                                        ifTrue: [ characterStack removeLast ]
                                        ifFalse: [ 
                                            (characterStack last = $[ and: [ char = $] ])
                                                ifTrue: [ characterStack removeLast ] ] ] ] ] ].
    ^ i - 1

I'm guessing I cribbed this from an ancient version of Pharo ... probably predates porting of RB to GemStone :)