Merge pull request #77 from hashicorp/phinze/poserror

add position to all decoder errors
This commit is contained in:
Paul Hinze 2015-12-18 11:53:00 -06:00
commit 197e8d3cf4

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"github.com/hashicorp/hcl/hcl/ast" "github.com/hashicorp/hcl/hcl/ast"
"github.com/hashicorp/hcl/hcl/parser"
"github.com/hashicorp/hcl/hcl/token" "github.com/hashicorp/hcl/hcl/token"
) )
@ -95,11 +96,11 @@ func (d *decoder) decode(name string, node ast.Node, result reflect.Value) error
case reflect.Struct: case reflect.Struct:
return d.decodeStruct(name, node, result) return d.decodeStruct(name, node, result)
default: default:
return fmt.Errorf( return &parser.PosError{
"%s: unknown kind to decode into: %s", name, k.Kind()) Pos: node.Pos(),
Err: fmt.Errorf("%s: unknown kind to decode into: %s", name, k.Kind()),
}
} }
return nil
} }
func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error { func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) error {
@ -116,7 +117,10 @@ func (d *decoder) decodeBool(name string, node ast.Node, result reflect.Value) e
} }
} }
return fmt.Errorf("%s: unknown type %T", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: unknown type %T", name, node),
}
} }
func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error { func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value) error {
@ -133,7 +137,10 @@ func (d *decoder) decodeFloat(name string, node ast.Node, result reflect.Value)
} }
} }
return fmt.Errorf("%s: unknown type %T", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: unknown type %T", name, node),
}
} }
func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error { func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) error {
@ -159,7 +166,10 @@ func (d *decoder) decodeInt(name string, node ast.Node, result reflect.Value) er
} }
} }
return fmt.Errorf("%s: unknown type %T", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: unknown type %T", name, node),
}
} }
func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error { func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Value) error {
@ -242,9 +252,10 @@ func (d *decoder) decodeInterface(name string, node ast.Node, result reflect.Val
case token.STRING, token.HEREDOC: case token.STRING, token.HEREDOC:
set = reflect.Indirect(reflect.New(reflect.TypeOf(""))) set = reflect.Indirect(reflect.New(reflect.TypeOf("")))
default: default:
return fmt.Errorf( return &parser.PosError{
"%s: cannot decode into interface: %T", Pos: node.Pos(),
name, node) Err: fmt.Errorf("%s: cannot decode into interface: %T", name, node),
}
} }
default: default:
return fmt.Errorf( return fmt.Errorf(
@ -278,7 +289,10 @@ func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) er
n, ok := node.(*ast.ObjectList) n, ok := node.(*ast.ObjectList)
if !ok { if !ok {
return fmt.Errorf("%s: not an object type for map (%T)", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: not an object type for map (%T)", name, node),
}
} }
// If we have an interface, then we can address the interface, // If we have an interface, then we can address the interface,
@ -292,8 +306,10 @@ func (d *decoder) decodeMap(name string, node ast.Node, result reflect.Value) er
resultElemType := resultType.Elem() resultElemType := resultType.Elem()
resultKeyType := resultType.Key() resultKeyType := resultType.Key()
if resultKeyType.Kind() != reflect.String { if resultKeyType.Kind() != reflect.String {
return fmt.Errorf( return &parser.PosError{
"%s: map must have string keys", name) Pos: node.Pos(),
Err: fmt.Errorf("%s: map must have string keys", name),
}
} }
// Make a map if it is nil // Make a map if it is nil
@ -397,7 +413,10 @@ func (d *decoder) decodeSlice(name string, node ast.Node, result reflect.Value)
case *ast.ListType: case *ast.ListType:
items = n.List items = n.List
default: default:
return fmt.Errorf("unknown slice type: %T", node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("unknown slice type: %T", node),
}
} }
for i, item := range items { for i, item := range items {
@ -430,7 +449,10 @@ func (d *decoder) decodeString(name string, node ast.Node, result reflect.Value)
} }
} }
return fmt.Errorf("%s: unknown type for string %T", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: unknown type for string %T", name, node),
}
} }
func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error { func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value) error {
@ -446,7 +468,10 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value)
list, ok := node.(*ast.ObjectList) list, ok := node.(*ast.ObjectList)
if !ok { if !ok {
return fmt.Errorf("%s: not an object type for struct (%T)", name, node) return &parser.PosError{
Pos: node.Pos(),
Err: fmt.Errorf("%s: not an object type for struct (%T)", name, node),
}
} }
// This slice will keep track of all the structs we'll be decoding. // This slice will keep track of all the structs we'll be decoding.
@ -469,9 +494,11 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value)
if fieldType.Anonymous { if fieldType.Anonymous {
fieldKind := fieldType.Type.Kind() fieldKind := fieldType.Type.Kind()
if fieldKind != reflect.Struct { if fieldKind != reflect.Struct {
return fmt.Errorf( return &parser.PosError{
"%s: unsupported type to struct: %s", Pos: node.Pos(),
fieldType.Name, fieldKind) Err: fmt.Errorf("%s: unsupported type to struct: %s",
fieldType.Name, fieldKind),
}
} }
// We have an embedded field. We "squash" the fields down // We have an embedded field. We "squash" the fields down
@ -524,9 +551,11 @@ func (d *decoder) decodeStruct(name string, node ast.Node, result reflect.Value)
continue continue
case "key": case "key":
if item == nil { if item == nil {
return fmt.Errorf( return &parser.PosError{
"%s: %s asked for 'key', impossible", Pos: node.Pos(),
name, fieldName) Err: fmt.Errorf("%s: %s asked for 'key', impossible",
name, fieldName),
}
} }
field.SetString(item.Keys[0].Token.Value().(string)) field.SetString(item.Keys[0].Token.Value().(string))