diff --git a/pkg/errchain/error.go b/pkg/errchain/error.go index 84cf7a5..54b409c 100644 --- a/pkg/errchain/error.go +++ b/pkg/errchain/error.go @@ -12,15 +12,16 @@ import ( "github.com/GuanceCloud/platypus/pkg/token" ) -type FilePos struct { - FilePath string - Ln int - Col int +type Position struct { + File string `json:"file"` // filename or filepath + Ln int `json:"ln"` + Col int `json:"col"` + Pos int `json:"pos"` } type PlError struct { - pos []FilePos - err string + PosChain []Position `json:"pos_chain"` + Err string `json:"error"` } type PlErrors []PlError @@ -34,50 +35,52 @@ func (e PlErrors) Error() string { } func (e *PlError) Error() string { - if len(e.pos) == 0 { + if len(e.PosChain) == 0 { return "" } var errr string - for i := 0; i < len(e.pos); i++ { - pos := e.pos[i] + for i := 0; i < len(e.PosChain); i++ { + pos := e.PosChain[i] if i == 0 { - errr += fmt.Sprintf("%s:%d:%d: %s", pos.FilePath, pos.Ln, pos.Col, e.err) + errr += fmt.Sprintf("%s:%d:%d: %s", pos.File, pos.Ln, pos.Col, e.Err) } else { errr += fmt.Sprintf( - "\n%s:%d:%d:", e.pos[i].FilePath, - e.pos[i].Ln, e.pos[i].Col) + "\n%s:%d:%d:", e.PosChain[i].File, + e.PosChain[i].Ln, e.PosChain[i].Col) } } return errr } -func (e *PlError) ChainAppend(filepath string, pos token.LnColPos) *PlError { - e.pos = append(e.pos, FilePos{ - Ln: pos.Ln, - Col: pos.Col, - FilePath: filepath, +func (e *PlError) ChainAppend(file string, pos token.LnColPos) *PlError { + e.PosChain = append(e.PosChain, Position{ + File: file, + Ln: pos.Ln, + Col: pos.Col, + Pos: int(pos.Pos), }) return e } func (e *PlError) Copy() *PlError { return &PlError{ - err: e.err, - pos: append([]FilePos{}, e.pos...), + Err: e.Err, + PosChain: append([]Position{}, e.PosChain...), } } -func NewErr(filepath string, pos token.LnColPos, err string) *PlError { +func NewErr(file string, pos token.LnColPos, err string) *PlError { return &PlError{ - pos: []FilePos{ + PosChain: []Position{ { - FilePath: filepath, - Col: pos.Col, - Ln: pos.Ln, + File: file, + Ln: pos.Ln, + Col: pos.Col, + Pos: int(pos.Pos), }, }, - err: err, + Err: err, } } diff --git a/pkg/errchain/error_test.go b/pkg/errchain/error_test.go new file mode 100644 index 0000000..ff1553d --- /dev/null +++ b/pkg/errchain/error_test.go @@ -0,0 +1,39 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the MIT License. +// This product includes software developed at Guance Cloud (https://www.guance.com/). +// Copyright 2021-present Guance, Inc. + +package errchain + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/GuanceCloud/platypus/pkg/token" + "github.com/stretchr/testify/assert" +) + +func TestConvPlErr2Json(t *testing.T) { + query := `a = 1 +b=2 +` + + pcache := token.NewPosCache(query) + err := NewErr("abc.p", pcache.LnCol(token.Pos(0)), "err") + + err = err.ChainAppend("d.p", pcache.LnCol(token.Pos(7))) + + errJSON := "{\"pos_chain\":[{\"file\":\"abc.p\",\"ln\":1,\"col\":1,\"pos\":0}," + + "{\"file\":\"d.p\",\"ln\":2,\"col\":2,\"pos\":7}],\"error\":\"err\"}\n" + + w := bytes.NewBuffer([]byte{}) + encoder := json.NewEncoder(w) + if e := encoder.Encode(err); e != nil { + t.Fatal(e) + } + + assert.Equal(t, errJSON, w.String()) + + assert.Equal(t, "abc.p:1:1: err\nd.p:2:2:", err.Error()) +} diff --git a/pkg/token/token.go b/pkg/token/token.go index 8200b61..4831f10 100644 --- a/pkg/token/token.go +++ b/pkg/token/token.go @@ -64,13 +64,13 @@ func (c *PosCache) LnCol(pos Pos) LnColPos { } return LnColPos{ + Pos: pos, Ln: int(ln) + 1, Col: int(pos) - c.lineStartPos[ln] + 1, } } func NewPosCache(query string) *PosCache { - cache := PosCache{ query: query, lineStartPos: []int{0},