Merge pull request #55 from hashicorp/f-error-pos

hcl/parser: store position on every parse err [GH-54]
This commit is contained in:
Mitchell Hashimoto 2015-11-15 15:08:40 -08:00
commit 2a326381fd
3 changed files with 51 additions and 8 deletions

17
hcl/parser/error.go Normal file
View File

@ -0,0 +1,17 @@
package parser
import (
"fmt"
"github.com/hashicorp/hcl/hcl/token"
)
// PosError is a parse error that contains a position.
type PosError struct {
Pos token.Pos
Err error
}
func (e *PosError) Error() string {
return fmt.Sprintf("At %s: %s", e.Pos, e.Err)
}

9
hcl/parser/error_test.go Normal file
View File

@ -0,0 +1,9 @@
package parser
import (
"testing"
)
func TestPosError_impl(t *testing.T) {
var _ error = new(PosError)
}

View File

@ -46,7 +46,7 @@ func (p *Parser) Parse() (*ast.File, error) {
f := &ast.File{}
var err, scerr error
p.sc.Error = func(pos token.Pos, msg string) {
scerr = fmt.Errorf("%s: %s", pos, msg)
scerr = &PosError{Pos: pos, Err: errors.New(msg)}
}
f.Node, err = p.objectList()
@ -173,11 +173,17 @@ func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
// assignment or object only, but not nested objects. this is not
// allowed: `foo bar = {}`
if keyCount > 1 {
return nil, fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type)
return nil, &PosError{
Pos: p.tok.Pos,
Err: fmt.Errorf("nested object expected: LBRACE got: %s", p.tok.Type),
}
}
if keyCount == 0 {
return nil, errors.New("no keys found!!!")
return nil, &PosError{
Pos: p.tok.Pos,
Err: errors.New("no object keys found!"),
}
}
return keys, nil
@ -190,7 +196,10 @@ func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
case token.ILLEGAL:
fmt.Println("illegal")
default:
return nil, fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type)
return nil, &PosError{
Pos: p.tok.Pos,
Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type),
}
}
}
}
@ -214,7 +223,10 @@ func (p *Parser) object() (ast.Node, error) {
return nil, errEofToken
}
return nil, fmt.Errorf("Unknown token: %+v", tok)
return nil, &PosError{
Pos: tok.Pos,
Err: fmt.Errorf("Unknown token: %+v", tok),
}
}
// objectType parses an object type and returns a ObjectType AST
@ -254,7 +266,10 @@ func (p *Parser) listType() (*ast.ListType, error) {
switch tok.Type {
case token.NUMBER, token.FLOAT, token.STRING:
if needComma {
return nil, fmt.Errorf("unexpected token: %s. Expecting %s", tok.Type, token.COMMA)
return nil, &PosError{
Pos: tok.Pos,
Err: fmt.Errorf("unexpected token: %s. Expecting %s", tok.Type, token.COMMA),
}
}
node, err := p.literalType()
@ -291,9 +306,11 @@ func (p *Parser) listType() (*ast.ListType, error) {
l.Rbrack = p.tok.Pos
return l, nil
default:
return nil, fmt.Errorf("unexpected token while parsing list: %s", tok.Type)
return nil, &PosError{
Pos: tok.Pos,
Err: fmt.Errorf("unexpected token while parsing list: %s", tok.Type),
}
}
}
}