d2parser: Allow passing in ParseError for nicer error messages in imports
This commit is contained in:
parent
c325e94cad
commit
f61409cb79
4 changed files with 17 additions and 17 deletions
|
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
type ParseOptions struct {
|
type ParseOptions struct {
|
||||||
UTF16 bool
|
UTF16 bool
|
||||||
|
ParseError *ParseError
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse parses a .d2 Map in r.
|
// Parse parses a .d2 Map in r.
|
||||||
|
|
@ -42,6 +43,10 @@ func Parse(path string, r io.RuneReader, opts *ParseOptions) (*d2ast.Map, error)
|
||||||
reader: r,
|
reader: r,
|
||||||
|
|
||||||
utf16: opts.UTF16,
|
utf16: opts.UTF16,
|
||||||
|
err: opts.ParseError,
|
||||||
|
}
|
||||||
|
if p.err == nil {
|
||||||
|
p.err = &ParseError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
m := p.parseMap(true)
|
m := p.parseMap(true)
|
||||||
|
|
@ -117,17 +122,15 @@ type parser struct {
|
||||||
lookaheadPos d2ast.Position
|
lookaheadPos d2ast.Position
|
||||||
|
|
||||||
ioerr bool
|
ioerr bool
|
||||||
err ParseError
|
err *ParseError
|
||||||
|
|
||||||
inEdgeGroup bool
|
inEdgeGroup bool
|
||||||
|
|
||||||
depth int
|
depth int
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove ioerr, just sort (with Append) should be fine but filter non ast errors in API
|
|
||||||
// TODO: rename to Error and make existing Error a private type errorWithRange
|
// TODO: rename to Error and make existing Error a private type errorWithRange
|
||||||
type ParseError struct {
|
type ParseError struct {
|
||||||
IOError *d2ast.Error `json:"ioerr"`
|
|
||||||
Errors []d2ast.Error `json:"errs"`
|
Errors []d2ast.Error `json:"errs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,17 +143,17 @@ func Errorf(n d2ast.Node, f string, v ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe ParseError) Empty() bool {
|
func (pe *ParseError) Empty() bool {
|
||||||
return pe.IOError == nil && len(pe.Errors) == 0
|
if pe == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return len(pe.Errors) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pe ParseError) Error() string {
|
func (pe *ParseError) Error() string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
if pe.IOError != nil {
|
|
||||||
sb.WriteString(pe.IOError.Error())
|
|
||||||
}
|
|
||||||
for i, err := range pe.Errors {
|
for i, err := range pe.Errors {
|
||||||
if pe.IOError != nil || i > 0 {
|
if i > 0 {
|
||||||
sb.WriteByte('\n')
|
sb.WriteByte('\n')
|
||||||
}
|
}
|
||||||
sb.WriteString(err.Error())
|
sb.WriteString(err.Error())
|
||||||
|
|
@ -191,14 +194,14 @@ func (p *parser) _readRune() (r rune, eof bool) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.ioerr = true
|
p.ioerr = true
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
p.err.IOError = &d2ast.Error{
|
p.err.Errors = append(p.err.Errors, d2ast.Error{
|
||||||
Range: d2ast.Range{
|
Range: d2ast.Range{
|
||||||
Path: p.path,
|
Path: p.path,
|
||||||
Start: p.readerPos,
|
Start: p.readerPos,
|
||||||
End: p.readerPos,
|
End: p.readerPos,
|
||||||
},
|
},
|
||||||
Message: fmt.Sprintf("io error: %v", err),
|
Message: fmt.Sprintf("io error: %v", err),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
p.rewind()
|
p.rewind()
|
||||||
return 0, true
|
return 0, true
|
||||||
|
|
|
||||||
1
testdata/d2parser/TestParse/bad_curly.exp.json
generated
vendored
1
testdata/d2parser/TestParse/bad_curly.exp.json
generated
vendored
|
|
@ -4,7 +4,6 @@
|
||||||
"nodes": null
|
"nodes": null
|
||||||
},
|
},
|
||||||
"err": {
|
"err": {
|
||||||
"ioerr": null,
|
|
||||||
"errs": [
|
"errs": [
|
||||||
{
|
{
|
||||||
"range": "d2/testdata/d2parser/TestParse/bad_curly.d2,0:3:3-0:4:4",
|
"range": "d2/testdata/d2parser/TestParse/bad_curly.d2,0:3:3-0:4:4",
|
||||||
|
|
|
||||||
1
testdata/d2parser/TestParse/errs.exp.json
generated
vendored
1
testdata/d2parser/TestParse/errs.exp.json
generated
vendored
|
|
@ -397,7 +397,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"err": {
|
"err": {
|
||||||
"ioerr": null,
|
|
||||||
"errs": [
|
"errs": [
|
||||||
{
|
{
|
||||||
"range": "d2/testdata/d2parser/TestParse/errs.d2,1:0:1-1:1:2",
|
"range": "d2/testdata/d2parser/TestParse/errs.d2,1:0:1-1:1:2",
|
||||||
|
|
|
||||||
1
testdata/d2parser/TestParse/missing_map_value.exp.json
generated
vendored
1
testdata/d2parser/TestParse/missing_map_value.exp.json
generated
vendored
|
|
@ -28,7 +28,6 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"err": {
|
"err": {
|
||||||
"ioerr": null,
|
|
||||||
"errs": [
|
"errs": [
|
||||||
{
|
{
|
||||||
"range": "d2/testdata/d2parser/TestParse/missing_map_value.d2,1:1:2-1:2:3",
|
"range": "d2/testdata/d2parser/TestParse/missing_map_value.d2,1:1:2-1:2:3",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue