Skip to content

Commit 4b7238e

Browse files
authored
multierr: Move dinosql.ParserErr to a new package (#496)
1 parent 5d28068 commit 4b7238e

File tree

6 files changed

+101
-79
lines changed

6 files changed

+101
-79
lines changed

internal/cmd/generate.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/kyleconroy/sqlc/internal/config"
1515
"github.com/kyleconroy/sqlc/internal/dinosql"
1616
"github.com/kyleconroy/sqlc/internal/dinosql/kotlin"
17+
"github.com/kyleconroy/sqlc/internal/multierr"
1718
"github.com/kyleconroy/sqlc/internal/mysql"
1819
)
1920

@@ -32,7 +33,7 @@ The only supported version is "1".
3233

3334
const errMessageNoPackages = `No packages are configured`
3435

35-
func printFileErr(stderr io.Writer, dir string, fileErr dinosql.FileErr) {
36+
func printFileErr(stderr io.Writer, dir string, fileErr *multierr.FileError) {
3637
filename := strings.TrimPrefix(fileErr.Filename, dir+"/")
3738
fmt.Fprintf(stderr, "%s:%d:%d: %s\n", filename, fileErr.Line, fileErr.Column, fileErr.Err)
3839
}
@@ -179,8 +180,8 @@ func parse(name, dir string, sql config.SQL, combo config.CombinedSettings, pars
179180
q, err := mysql.GeneratePkg(name, sql.Schema, sql.Queries, combo)
180181
if err != nil {
181182
fmt.Fprintf(stderr, "# package %s\n", name)
182-
if parserErr, ok := err.(*dinosql.ParserErr); ok {
183-
for _, fileErr := range parserErr.Errs {
183+
if parserErr, ok := err.(*multierr.Error); ok {
184+
for _, fileErr := range parserErr.Errs() {
184185
printFileErr(stderr, dir, fileErr)
185186
}
186187
} else {
@@ -194,8 +195,8 @@ func parse(name, dir string, sql config.SQL, combo config.CombinedSettings, pars
194195
c, err := dinosql.ParseCatalog(sql.Schema)
195196
if err != nil {
196197
fmt.Fprintf(stderr, "# package %s\n", name)
197-
if parserErr, ok := err.(*dinosql.ParserErr); ok {
198-
for _, fileErr := range parserErr.Errs {
198+
if parserErr, ok := err.(*multierr.Error); ok {
199+
for _, fileErr := range parserErr.Errs() {
199200
printFileErr(stderr, dir, fileErr)
200201
}
201202
} else {
@@ -207,8 +208,8 @@ func parse(name, dir string, sql config.SQL, combo config.CombinedSettings, pars
207208
q, err := dinosql.ParseQueries(c, sql.Queries, parserOpts)
208209
if err != nil {
209210
fmt.Fprintf(stderr, "# package %s\n", name)
210-
if parserErr, ok := err.(*dinosql.ParserErr); ok {
211-
for _, fileErr := range parserErr.Errs {
211+
if parserErr, ok := err.(*multierr.Error); ok {
212+
for _, fileErr := range parserErr.Errs() {
212213
printFileErr(stderr, dir, fileErr)
213214
}
214215
} else {

internal/dinosql/parser.go

Lines changed: 5 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/kyleconroy/sqlc/internal/catalog"
1515
"github.com/kyleconroy/sqlc/internal/migrations"
16+
"github.com/kyleconroy/sqlc/internal/multierr"
1617
core "github.com/kyleconroy/sqlc/internal/pg"
1718
"github.com/kyleconroy/sqlc/internal/postgres"
1819
"github.com/kyleconroy/sqlc/internal/postgresql/ast"
@@ -27,46 +28,13 @@ func keepSpew() {
2728
spew.Dump("hello world")
2829
}
2930

30-
type FileErr struct {
31-
Filename string
32-
Line int
33-
Column int
34-
Err error
35-
}
36-
37-
type ParserErr struct {
38-
Errs []FileErr
39-
}
40-
41-
func (e *ParserErr) Add(filename, source string, loc int, err error) {
42-
line := 1
43-
column := 1
44-
if lerr, ok := err.(core.Error); ok {
45-
if lerr.Location != 0 {
46-
loc = lerr.Location
47-
}
48-
}
49-
if source != "" && loc != 0 {
50-
line, column = lineno(source, loc)
51-
}
52-
e.Errs = append(e.Errs, FileErr{filename, line, column, err})
53-
}
54-
55-
func NewParserErr() *ParserErr {
56-
return &ParserErr{}
57-
}
58-
59-
func (e *ParserErr) Error() string {
60-
return fmt.Sprintf("multiple errors: %d errors", len(e.Errs))
61-
}
62-
6331
func ParseCatalog(schemas []string) (core.Catalog, error) {
6432
files, err := sqlpath.Glob(schemas)
6533
if err != nil {
6634
return core.Catalog{}, err
6735
}
6836

69-
merr := NewParserErr()
37+
merr := multierr.New()
7038
c := core.NewCatalog()
7139
for _, filename := range files {
7240
blob, err := ioutil.ReadFile(filename)
@@ -96,7 +64,7 @@ func ParseCatalog(schemas []string) (core.Catalog, error) {
9664
// catalog so that other queries can not read from it.
9765
delete(c.Schemas, "pg_temp")
9866

99-
if len(merr.Errs) > 0 {
67+
if len(merr.Errs()) > 0 {
10068
return c, merr
10169
}
10270
return c, nil
@@ -163,7 +131,7 @@ type ParserOpts struct {
163131
}
164132

165133
func ParseQueries(c core.Catalog, queriesPaths []string, opts ParserOpts) (*Result, error) {
166-
merr := NewParserErr()
134+
merr := multierr.New()
167135
var q []*Query
168136

169137
set := map[string]struct{}{}
@@ -205,7 +173,7 @@ func ParseQueries(c core.Catalog, queriesPaths []string, opts ParserOpts) (*Resu
205173
}
206174
}
207175
}
208-
if len(merr.Errs) > 0 {
176+
if len(merr.Errs()) > 0 {
209177
return nil, merr
210178
}
211179
if len(q) == 0 {
@@ -227,36 +195,6 @@ func location(node nodes.Node) int {
227195
return 0
228196
}
229197

230-
func lineno(source string, head int) (int, int) {
231-
// Calculate the true line and column number for a query, ignoring spaces
232-
var comment bool
233-
var loc, line, col int
234-
for i, char := range source {
235-
loc += 1
236-
col += 1
237-
// TODO: Check bounds
238-
if char == '-' && source[i+1] == '-' {
239-
comment = true
240-
}
241-
if char == '\n' {
242-
comment = false
243-
line += 1
244-
col = 0
245-
}
246-
if loc <= head {
247-
continue
248-
}
249-
if unicode.IsSpace(char) {
250-
continue
251-
}
252-
if comment {
253-
continue
254-
}
255-
break
256-
}
257-
return line + 1, col
258-
}
259-
260198
func pluckQuery(source string, n nodes.RawStmt) (string, error) {
261199
head := n.StmtLocation
262200
tail := n.StmtLocation + n.StmtLen

internal/dinosql/parser_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path"
77
"testing"
88

9+
"github.com/kyleconroy/sqlc/internal/source"
910
"github.com/kyleconroy/sqlc/internal/sql/sqlpath"
1011

1112
"github.com/google/go-cmp/cmp"
@@ -81,7 +82,7 @@ func TestLineColumn(t *testing.T) {
8182
{tree.Statements[5], 10, 12},
8283
} {
8384
raw := test.node.(nodes.RawStmt)
84-
line, column := lineno(lineColumn, raw.StmtLocation)
85+
line, column := source.LineNumber(lineColumn, raw.StmtLocation)
8586
if line != test.line {
8687
t.Errorf("expected stmt %d to be on line %d, not %d", i, test.line, line)
8788
}

internal/multierr/error.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package multierr
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/kyleconroy/sqlc/internal/pg"
7+
"github.com/kyleconroy/sqlc/internal/source"
8+
)
9+
10+
type FileError struct {
11+
Filename string
12+
Line int
13+
Column int
14+
Err error
15+
}
16+
17+
func (e *FileError) Unwrap() error {
18+
return e.Err
19+
}
20+
21+
type Error struct {
22+
errs []*FileError
23+
}
24+
25+
func (e *Error) Add(filename, in string, loc int, err error) {
26+
line := 1
27+
column := 1
28+
if lerr, ok := err.(pg.Error); ok {
29+
if lerr.Location != 0 {
30+
loc = lerr.Location
31+
}
32+
}
33+
if in != "" && loc != 0 {
34+
line, column = source.LineNumber(in, loc)
35+
}
36+
e.errs = append(e.errs, &FileError{filename, line, column, err})
37+
}
38+
39+
func (e *Error) Errs() []*FileError {
40+
return e.errs
41+
}
42+
43+
func (e *Error) Error() string {
44+
return fmt.Sprintf("multiple errors: %d errors", len(e.errs))
45+
}
46+
47+
func New() *Error {
48+
return &Error{}
49+
}

internal/mysql/parse.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/kyleconroy/sqlc/internal/config"
1313
"github.com/kyleconroy/sqlc/internal/dinosql"
1414
"github.com/kyleconroy/sqlc/internal/migrations"
15+
"github.com/kyleconroy/sqlc/internal/multierr"
1516
"github.com/kyleconroy/sqlc/internal/sql/sqlpath"
1617
)
1718

@@ -38,8 +39,7 @@ func parsePath(sqlPath []string, generator PackageGenerator) (*Result, error) {
3839
return nil, err
3940
}
4041

41-
parseErrors := dinosql.ParserErr{}
42-
42+
parseErrors := multierr.New()
4343
parsedQueries := []*Query{}
4444
for _, filename := range files {
4545
blob, err := ioutil.ReadFile(filename)
@@ -86,8 +86,8 @@ func parsePath(sqlPath []string, generator PackageGenerator) (*Result, error) {
8686
}
8787
}
8888

89-
if len(parseErrors.Errs) > 0 {
90-
return nil, &parseErrors
89+
if len(parseErrors.Errs()) > 0 {
90+
return nil, parseErrors
9191
}
9292

9393
return &Result{

internal/source/code.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package source
2+
3+
import "unicode"
4+
5+
func LineNumber(source string, head int) (int, int) {
6+
// Calculate the true line and column number for a query, ignoring spaces
7+
var comment bool
8+
var loc, line, col int
9+
for i, char := range source {
10+
loc += 1
11+
col += 1
12+
// TODO: Check bounds
13+
if char == '-' && source[i+1] == '-' {
14+
comment = true
15+
}
16+
if char == '\n' {
17+
comment = false
18+
line += 1
19+
col = 0
20+
}
21+
if loc <= head {
22+
continue
23+
}
24+
if unicode.IsSpace(char) {
25+
continue
26+
}
27+
if comment {
28+
continue
29+
}
30+
break
31+
}
32+
return line + 1, col
33+
}

0 commit comments

Comments
 (0)