Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/MontFerret/contrib/modules/web/sitemap v1.0.0-rc.16
github.com/MontFerret/contrib/modules/xml v1.0.0-rc.16
github.com/MontFerret/contrib/modules/yaml v1.0.0-rc.16
github.com/MontFerret/ferret/v2 v2.0.0-alpha.54
github.com/MontFerret/ferret/v2 v2.0.0-alpha.55
github.com/MontFerret/specs v1.12.0
github.com/antlr4-go/antlr/v4 v4.13.1
github.com/chzyer/readline v1.5.1
Expand All @@ -46,7 +46,7 @@ require (
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/JohannesKaufmann/dom v0.3.1 // indirect
github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2 // indirect
github.com/MontFerret/api v1.0.0-alpha.16 // indirect
github.com/MontFerret/api v1.0.0-alpha.19 // indirect
github.com/MontFerret/contrib/pkg/common v0.2.0 // indirect
github.com/MontFerret/cssx v0.2.0 // indirect
github.com/PuerkitoBio/goquery v1.13.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2 h1:XFJZFWESIWlUEHHjzBuv8R
github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2/go.mod h1:BHWO8lJzttJLqwuV8Rb1B3OG2OSzLbssZDI1FRg2eAA=
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/MontFerret/api v1.0.0-alpha.16 h1:OhAyPzy3s57BHiI0mHn4HLv456985nmWCtQgSdUESXg=
github.com/MontFerret/api v1.0.0-alpha.16/go.mod h1:wz5bfUIGYkED8Hqz9CdsW0o2jSgagotbVLOCbHHacSI=
github.com/MontFerret/api v1.0.0-alpha.19 h1:zRAb2rAMFxhKggmVTEEQfWxfaSz6+p5D6b+C5P/RXZw=
github.com/MontFerret/api v1.0.0-alpha.19/go.mod h1:wz5bfUIGYkED8Hqz9CdsW0o2jSgagotbVLOCbHHacSI=
github.com/MontFerret/barn v1.4.0 h1:68L+WFVxqPKuxuAj5f8CLBDmo/xnv6q0sxl4+GrrDmc=
github.com/MontFerret/barn v1.4.0/go.mod h1:7+5uWWREpGgGppWjiEf8qCQuZyf+QshDr8zy4XaFSlA=
github.com/MontFerret/contrib/modules/ai/llm v1.0.0-rc.6 h1:d3F2WWcGdTmYVXfNTTFVXDEonWpTSfmcde2GzOFsGgE=
Expand Down Expand Up @@ -50,8 +50,8 @@ github.com/MontFerret/contrib/pkg/common v0.2.0 h1:/ftEguEPPg7tGTAHUkTzu4y+nW234
github.com/MontFerret/contrib/pkg/common v0.2.0/go.mod h1:bgwvpoX6xgEIWRQvEmftgsgbs2JER0DHqMqXqyuWq6E=
github.com/MontFerret/cssx v0.2.0 h1:De0C6Irbg+qgFPXgWmPpVnwD4RRYUBQSbIYFTUVCNWU=
github.com/MontFerret/cssx v0.2.0/go.mod h1:fmGtRUNVaeJYpiPSDlNIbbYzb3+K8NxmNmJOYqlHATU=
github.com/MontFerret/ferret/v2 v2.0.0-alpha.54 h1:Csrf/CEsqmuSp0s/nDbnnkmXQtIHuWVLCuzGNNUlFu4=
github.com/MontFerret/ferret/v2 v2.0.0-alpha.54/go.mod h1:6okTqyD30H5pCa8yXHQfpEzgRZWAsHgx68K6DTcDHek=
github.com/MontFerret/ferret/v2 v2.0.0-alpha.55 h1:ylh5oXP8smLSo9P40a52bOQWBF9kk8EAIe6/atWWsck=
github.com/MontFerret/ferret/v2 v2.0.0-alpha.55/go.mod h1:wjyA9O+zZHXn5+izgqOhuhkdHk9irwL8YsUKPCRRNRk=
github.com/MontFerret/specs v1.12.0 h1:1HaElGLN+tyZIsrb3WVdulxbW5W0LXEdOH0k6F1sFzk=
github.com/MontFerret/specs v1.12.0/go.mod h1:ENGyEPFjrWVPWOUAsBMc1acUsqpswieTrAJfhcm576E=
github.com/PuerkitoBio/goquery v1.13.0 h1:mqHbjD7Jmnul4DTR24LKTjo1uUmHUh072kteGV+xpFM=
Expand Down
23 changes: 23 additions & 0 deletions pkg/debugger/fake_line_reader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package debugger

import "io"

type lineResult struct {
line string
err error
}

type fakeLineReader struct {
results []lineResult
index int
}

func (f *fakeLineReader) Readline() (string, error) {
if f.index >= len(f.results) {
return "", io.EOF
}

result := f.results[f.index]
f.index++
return result.line, result.err
}
141 changes: 141 additions & 0 deletions pkg/debugger/fake_session_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package debugger

import (
"context"

"github.com/MontFerret/ferret/v2"
ferruntime "github.com/MontFerret/ferret/v2/pkg/runtime"
"github.com/MontFerret/ferret/v2/pkg/source"
)

type fakeSession struct {
startEvent *ferret.DebugEvent
continueEvent *ferret.DebugEvent
locals []ferret.DebugVariable
frames []ferret.DebugFrame
breakpoints []ferret.DebugBreakpoint
evaluation ferret.DebugValue
continueErr error
evaluateErr error
breakpointsErr error
contexts map[CommandName]context.Context
expression string
closeErr error
breakpointLocation ferret.DebugSourceLocation
breakpointOptions ferret.DebugBreakpointOptions
startCalls int
continueCalls int
stepCalls int
nextCalls int
outCalls int
pauseCalls int
setBreakpointCalls int
deleteCalls int
breakpointsCalls int
framesCalls int
localsCalls int
evaluateCalls int
closeCalls int
}

func (f *fakeSession) Start(context.Context) (*ferret.DebugEvent, error) {
f.startCalls++
return f.startEvent, nil
}

func (f *fakeSession) Continue(context.Context) (*ferret.DebugEvent, error) {
f.continueCalls++
return f.continueEvent, f.continueErr
}

func (f *fakeSession) StepIn(context.Context) (*ferret.DebugEvent, error) {
f.stepCalls++
return f.continueEvent, nil
}

func (f *fakeSession) StepOver(context.Context) (*ferret.DebugEvent, error) {
f.nextCalls++
return f.continueEvent, nil
}

func (f *fakeSession) StepOut(context.Context) (*ferret.DebugEvent, error) {
f.outCalls++
return f.continueEvent, nil
}

func (f *fakeSession) Pause(ctx context.Context) error {
f.pauseCalls++
f.recordContext(ctx, CommandPause)

return nil
}

func (f *fakeSession) SetBreakpointAt(ctx context.Context, location ferret.DebugSourceLocation, options ferret.DebugBreakpointOptions) (ferret.DebugBreakpoint, error) {
f.setBreakpointCalls++
f.recordContext(ctx, CommandBreak)
f.breakpointLocation = location
f.breakpointOptions = options
breakpoint := ferret.DebugBreakpoint{
ID: ferret.DebugBreakpointID(len(f.breakpoints) + 1),
RequestedLocation: location,
Location: debugLocation(location.SourceName, location.Line, location.Column, source.Span{}),
BindingMode: options.BindingMode,
Bound: true,
}
f.breakpoints = append(f.breakpoints, breakpoint)
return breakpoint, nil
}

func (f *fakeSession) DeleteBreakpoint(ctx context.Context, id ferret.DebugBreakpointID) error {
f.deleteCalls++
f.recordContext(ctx, CommandDelete)

for i, breakpoint := range f.breakpoints {
if breakpoint.ID == id {
f.breakpoints = append(f.breakpoints[:i], f.breakpoints[i+1:]...)
return nil
}
}

return ferruntime.Errorf(ferruntime.ErrNotFound, "breakpoint %d", id)
}

func (f *fakeSession) Breakpoints(ctx context.Context) ([]ferret.DebugBreakpoint, error) {
f.breakpointsCalls++
f.recordContext(ctx, CommandBreakpoints)

return f.breakpoints, f.breakpointsErr
}

func (f *fakeSession) Frames(ctx context.Context) ([]ferret.DebugFrame, error) {
f.framesCalls++
f.recordContext(ctx, CommandWhere)

return f.frames, nil
}

func (f *fakeSession) Locals(ctx context.Context) ([]ferret.DebugVariable, error) {
f.localsCalls++
f.recordContext(ctx, CommandLocals)

return f.locals, nil
}

func (f *fakeSession) Evaluate(_ context.Context, expression string) (ferret.DebugValue, error) {
f.evaluateCalls++
f.expression = expression
return f.evaluation, f.evaluateErr
}

func (f *fakeSession) Close() error {
f.closeCalls++
return f.closeErr
}

func (f *fakeSession) recordContext(ctx context.Context, command CommandName) {
if f.contexts == nil {
f.contexts = make(map[CommandName]context.Context)
}

f.contexts[command] = ctx
}
20 changes: 11 additions & 9 deletions pkg/debugger/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,14 @@ func executeCommand(ctx context.Context, session Session, mainSourceName string,
location.SourceName = mainSourceName
}

breakpoint, err := session.SetBreakpointAt(location, command.BreakpointOptions)

breakpoint, err := session.SetBreakpointAt(ctx, location, command.BreakpointOptions)
if err != nil {
renderer.Error("Breakpoint error", err)
} else {
renderer.BreakpointSet(breakpoint)
}
case CommandDelete:
if err := session.DeleteBreakpoint(command.BreakpointID); err != nil {
if err := session.DeleteBreakpoint(ctx, command.BreakpointID); err != nil {
if errors.Is(err, runtime.ErrNotFound) {
fmt.Fprintf(renderer.out, "Unknown breakpoint: %d\n", command.BreakpointID)
} else {
Expand All @@ -140,7 +139,12 @@ func executeCommand(ctx context.Context, session Session, mainSourceName string,
fmt.Fprintf(renderer.out, "Breakpoint %d deleted.\n", command.BreakpointID)
}
case CommandBreakpoints:
renderer.Breakpoints(session.Breakpoints())
breakpoints, err := session.Breakpoints(ctx)
if err != nil {
renderer.Error("Breakpoints error", err)
} else {
renderer.Breakpoints(breakpoints)
}
case CommandContinue:
event, err := session.Continue(ctx)
return false, renderResume(event, err, renderer)
Expand All @@ -154,22 +158,20 @@ func executeCommand(ctx context.Context, session Session, mainSourceName string,
event, err := session.StepOut(ctx)
return false, renderResume(event, err, renderer)
case CommandPause:
if err := session.Pause(); err != nil {
if err := session.Pause(ctx); err != nil {
renderer.Error("Pause error", err)
} else {
fmt.Fprintln(renderer.out, "Pause requested.")
}
case CommandWhere:
frames, err := session.Frames()

frames, err := session.Frames(ctx)
if err != nil {
renderer.Error("Stack error", err)
} else {
renderer.Frames(frames)
}
case CommandLocals:
locals, err := session.Locals()

locals, err := session.Locals(ctx)
if err != nil {
renderer.Error("Locals error", err)
} else {
Expand Down
Loading