Merge pull request #102 from hashicorp/b-bare-keys
Parse error on keys without values
This commit is contained in:
commit
567a5d1c48
@ -5,6 +5,7 @@ package parser
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/hcl/hcl/ast"
|
"github.com/hashicorp/hcl/hcl/ast"
|
||||||
"github.com/hashicorp/hcl/hcl/scanner"
|
"github.com/hashicorp/hcl/hcl/scanner"
|
||||||
@ -122,6 +123,24 @@ func (p *Parser) objectItem() (*ast.ObjectItem, error) {
|
|||||||
defer un(trace(p, "ParseObjectItem"))
|
defer un(trace(p, "ParseObjectItem"))
|
||||||
|
|
||||||
keys, err := p.objectKey()
|
keys, err := p.objectKey()
|
||||||
|
if len(keys) > 0 && err == errEofToken {
|
||||||
|
// We ignore eof token here since it is an error if we didn't
|
||||||
|
// receive a value (but we did receive a key) for the item.
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if len(keys) > 0 && err != nil && p.tok.Type == token.RBRACE {
|
||||||
|
// This is a strange boolean statement, but what it means is:
|
||||||
|
// We have keys with no value, and we're likely in an object
|
||||||
|
// (since RBrace ends an object). For this, we set err to nil so
|
||||||
|
// we continue and get the error below of having the wrong value
|
||||||
|
// type.
|
||||||
|
err = nil
|
||||||
|
|
||||||
|
// Reset the token type so we don't think it completed fine. See
|
||||||
|
// objectType which uses p.tok.Type to check if we're done with
|
||||||
|
// the object.
|
||||||
|
p.tok.Type = token.EOF
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -147,6 +166,15 @@ func (p *Parser) objectItem() (*ast.ObjectItem, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
keyStr := make([]string, 0, len(keys))
|
||||||
|
for _, k := range keys {
|
||||||
|
keyStr = append(keyStr, k.Token.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf(
|
||||||
|
"key '%s' expected start of object ('{') or assignment ('=')",
|
||||||
|
strings.Join(keyStr, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// do a look-ahead for line comment
|
// do a look-ahead for line comment
|
||||||
@ -168,7 +196,11 @@ func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
|
|||||||
tok := p.scan()
|
tok := p.scan()
|
||||||
switch tok.Type {
|
switch tok.Type {
|
||||||
case token.EOF:
|
case token.EOF:
|
||||||
return nil, errEofToken
|
// It is very important to also return the keys here as well as
|
||||||
|
// the error. This is because we need to be able to tell if we
|
||||||
|
// did parse keys prior to finding the EOF, or if we just found
|
||||||
|
// a bare EOF.
|
||||||
|
return keys, errEofToken
|
||||||
case token.ASSIGN:
|
case token.ASSIGN:
|
||||||
// assignment or object only, but not nested objects. this is not
|
// assignment or object only, but not nested objects. this is not
|
||||||
// allowed: `foo bar = {}`
|
// allowed: `foo bar = {}`
|
||||||
@ -196,7 +228,7 @@ func (p *Parser) objectKey() ([]*ast.ObjectKey, error) {
|
|||||||
case token.ILLEGAL:
|
case token.ILLEGAL:
|
||||||
fmt.Println("illegal")
|
fmt.Println("illegal")
|
||||||
default:
|
default:
|
||||||
return nil, &PosError{
|
return keys, &PosError{
|
||||||
Pos: p.tok.Pos,
|
Pos: p.tok.Pos,
|
||||||
Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type),
|
Err: fmt.Errorf("expected: IDENT | STRING | ASSIGN | LBRACE got: %s", p.tok.Type),
|
||||||
}
|
}
|
||||||
|
@ -307,6 +307,14 @@ func TestParse(t *testing.T) {
|
|||||||
"unterminated_object_2.hcl",
|
"unterminated_object_2.hcl",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key_without_value.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object_key_without_value.hcl",
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const fixtureDir = "./test-fixtures"
|
const fixtureDir = "./test-fixtures"
|
||||||
|
1
hcl/parser/test-fixtures/key_without_value.hcl
Normal file
1
hcl/parser/test-fixtures/key_without_value.hcl
Normal file
@ -0,0 +1 @@
|
|||||||
|
foo
|
3
hcl/parser/test-fixtures/object_key_without_value.hcl
Normal file
3
hcl/parser/test-fixtures/object_key_without_value.hcl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
foo {
|
||||||
|
bar
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user