Skip to content

Commit

Permalink
feat: aggregate go build errors for LSP
Browse files Browse the repository at this point in the history
fixes #1233
fixes #1237
  • Loading branch information
worstell committed Apr 15, 2024
1 parent 46e8650 commit 1f3706d
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 265 deletions.
23 changes: 19 additions & 4 deletions backend/schema/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package schema
import (
"errors"
"fmt"
"sort"

schemapb "github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/schema"
)
Expand Down Expand Up @@ -66,11 +67,12 @@ func ErrorListFromProto(e *schemapb.ErrorList) *ErrorList {
}
}

func Errorf(pos Position, endColumn int, format string, args ...any) Error {
return Error{Msg: fmt.Sprintf(format, args...), Pos: pos, EndColumn: endColumn}
func Errorf(pos Position, endColumn int, format string, args ...any) *Error {
err := Error{Msg: fmt.Sprintf(format, args...), Pos: pos, EndColumn: endColumn}
return &err
}

func Wrapf(pos Position, endColumn int, err error, format string, args ...any) Error {
func Wrapf(pos Position, endColumn int, err error, format string, args ...any) *Error {
if format == "" {
format = "%s"
} else {
Expand All @@ -88,5 +90,18 @@ func Wrapf(pos Position, endColumn int, err error, format string, args ...any) E
newEndColumn = endColumn
args = append(args, err)
}
return Error{Msg: fmt.Sprintf(format, args...), Pos: newPos, EndColumn: newEndColumn}
e := Error{Msg: fmt.Sprintf(format, args...), Pos: newPos, EndColumn: newEndColumn}
return &e
}

func SortErrorsByPosition(merr []error) {
sort.Slice(merr, func(i, j int) bool {
var ipe, jpe Error
if errors.As(merr[i], &ipe) && errors.As(merr[j], &jpe) {
ipp := ipe.Pos
jpp := jpe.Pos
return ipp.Line < jpp.Line || (ipp.Line == jpp.Line && ipp.Column < jpp.Column)
}
return merr[i].Error() < merr[j].Error()
})
}
1 change: 1 addition & 0 deletions buildengine/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func buildModule(ctx context.Context, sch *schema.Schema, module Module) error {
for _, e := range errorList.Errors {
errs = append(errs, *e)
}
schema.SortErrorsByPosition(errs)
return errors.Join(errs...)
}

Expand Down
2 changes: 1 addition & 1 deletion buildengine/build_go_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,6 @@ func TestExternalType(t *testing.T) {
sch: &schema.Schema{},
}
testBuild(t, bctx, true, []assertion{
assertBuildProtoErrors("field Month: unsupported external type time.Month"),
assertBuildProtoErrors("unsupported external type \"time.Month\""),
})
}
4 changes: 2 additions & 2 deletions go-runtime/compile/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ func Build(ctx context.Context, moduleDir string, sch *schema.Schema) error {
if originalErr := err; err != nil {
var schemaErrs []*schema.Error
for _, e := range errors.DeduplicateErrors(errors.UnwrapAll(err)) {
var ce schema.Error
var ce *schema.Error
if errors.As(e, &ce) {
schemaErrs = append(schemaErrs, &ce)
schemaErrs = append(schemaErrs, ce)
}
}
el := schema.ErrorList{
Expand Down
9 changes: 5 additions & 4 deletions go-runtime/compile/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ var directiveParser = participle.MustBuild[directiveWrapper](
participle.Union[schema.IngressPathComponent](&schema.IngressPathLiteral{}, &schema.IngressPathParameter{}),
)

func parseDirectives(fset *token.FileSet, docs *ast.CommentGroup) ([]directive, error) {
func parseDirectives(node ast.Node, fset *token.FileSet, docs *ast.CommentGroup) ([]directive, *schema.Error) {
if docs == nil {
return nil, nil
}
Expand All @@ -86,17 +86,18 @@ func parseDirectives(fset *token.FileSet, docs *ast.CommentGroup) ([]directive,
directive, err := directiveParser.ParseString(pos.Filename, line.Text[2:])
if err != nil {
// Adjust the Participle-reported position relative to the AST node.
var scerr *schema.Error
var perr participle.Error
if errors.As(err, &perr) {
ppos := schema.Position{}
ppos.Filename = pos.Filename
ppos.Column += pos.Column + 2
ppos.Line = pos.Line
err = schema.Errorf(ppos, ppos.Column, "%s", perr.Message())
scerr = schema.Errorf(ppos, ppos.Column, "%s", perr.Message())
} else {
err = fmt.Errorf("%s: %w", pos, err)
scerr = wrapf(node, err, "")
}
return nil, fmt.Errorf("invalid directive: %w", err)
return nil, scerr
}
directives = append(directives, directive.Directive)
}
Expand Down
Loading

0 comments on commit 1f3706d

Please sign in to comment.