Rename group to table (#115)

* Rename Group to Table Fixes #45 
* Change fmt.Errorf to errors.new for simple strings
This commit is contained in:
Thomas Pelletier
2016-12-03 12:32:16 +01:00
committed by GitHub
parent d464759235
commit ce7be745f0
7 changed files with 67 additions and 66 deletions
+6 -5
View File
@@ -4,6 +4,7 @@ package toml
import (
"bytes"
"errors"
"fmt"
"unicode"
)
@@ -47,7 +48,7 @@ func parseKey(key string) ([]string, error) {
} else {
if !wasInQuotes {
if buffer.Len() == 0 {
return nil, fmt.Errorf("empty key group")
return nil, errors.New("empty table key")
}
groups = append(groups, buffer.String())
buffer.Reset()
@@ -67,23 +68,23 @@ func parseKey(key string) ([]string, error) {
return nil, fmt.Errorf("invalid bare character: %c", char)
}
if !inQuotes && expectDot {
return nil, fmt.Errorf("what?")
return nil, errors.New("what?")
}
buffer.WriteRune(char)
expectDot = false
}
}
if inQuotes {
return nil, fmt.Errorf("mismatched quotes")
return nil, errors.New("mismatched quotes")
}
if escapeNext {
return nil, fmt.Errorf("unfinished escape sequence")
return nil, errors.New("unfinished escape sequence")
}
if buffer.Len() > 0 {
groups = append(groups, buffer.String())
}
if len(groups) == 0 {
return nil, fmt.Errorf("empty key")
return nil, errors.New("empty key")
}
return groups, nil
}
+12 -12
View File
@@ -129,7 +129,7 @@ func (l *tomlLexer) lexVoid() tomlLexStateFn {
next := l.peek()
switch next {
case '[':
return l.lexKeyGroup
return l.lexTableKey
case '#':
return l.lexComment
case '=':
@@ -516,21 +516,21 @@ func (l *tomlLexer) lexString() tomlLexStateFn {
return l.lexRvalue
}
func (l *tomlLexer) lexKeyGroup() tomlLexStateFn {
func (l *tomlLexer) lexTableKey() tomlLexStateFn {
l.next()
if l.peek() == '[' {
// token '[[' signifies an array of anonymous key groups
// token '[[' signifies an array of tables
l.next()
l.emit(tokenDoubleLeftBracket)
return l.lexInsideKeyGroupArray
return l.lexInsideTableArrayKey
}
// vanilla key group
// vanilla table key
l.emit(tokenLeftBracket)
return l.lexInsideKeyGroup
return l.lexInsideTableKey
}
func (l *tomlLexer) lexInsideKeyGroupArray() tomlLexStateFn {
func (l *tomlLexer) lexInsideTableArrayKey() tomlLexStateFn {
for r := l.peek(); r != eof; r = l.peek() {
switch r {
case ']':
@@ -545,15 +545,15 @@ func (l *tomlLexer) lexInsideKeyGroupArray() tomlLexStateFn {
l.emit(tokenDoubleRightBracket)
return l.lexVoid
case '[':
return l.errorf("group name cannot contain ']'")
return l.errorf("table array key cannot contain ']'")
default:
l.next()
}
}
return l.errorf("unclosed key group array")
return l.errorf("unclosed table array key")
}
func (l *tomlLexer) lexInsideKeyGroup() tomlLexStateFn {
func (l *tomlLexer) lexInsideTableKey() tomlLexStateFn {
for r := l.peek(); r != eof; r = l.peek() {
switch r {
case ']':
@@ -564,12 +564,12 @@ func (l *tomlLexer) lexInsideKeyGroup() tomlLexStateFn {
l.emit(tokenRightBracket)
return l.lexVoid
case '[':
return l.errorf("group name cannot contain ']'")
return l.errorf("table key cannot contain ']'")
default:
l.next()
}
}
return l.errorf("unclosed key group")
return l.errorf("unclosed table key")
}
func (l *tomlLexer) lexRightBracket() tomlLexStateFn {
+1 -1
View File
@@ -56,7 +56,7 @@ func TestNestedQuotedUnicodeKeyGroup(t *testing.T) {
func TestUnclosedKeyGroup(t *testing.T) {
testFlow(t, "[hello world", []token{
{Position{1, 1}, tokenLeftBracket, "["},
{Position{1, 2}, tokenError, "unclosed key group"},
{Position{1, 2}, tokenError, "unclosed table key"},
})
}
+35 -34
View File
@@ -3,6 +3,7 @@
package toml
import (
"errors"
"fmt"
"reflect"
"regexp"
@@ -15,8 +16,8 @@ type tomlParser struct {
flow chan token
tree *TomlTree
tokensBuffer []token
currentGroup []string
seenGroupKeys []string
currentTable []string
seenTableKeys []string
}
type tomlParserStateFn func() tomlParserStateFn
@@ -95,13 +96,13 @@ func (p *tomlParser) parseGroupArray() tomlParserStateFn {
startToken := p.getToken() // discard the [[
key := p.getToken()
if key.typ != tokenKeyGroupArray {
p.raiseError(key, "unexpected token %s, was expecting a key group array", key)
p.raiseError(key, "unexpected token %s, was expecting a table array key", key)
}
// get or create group array element at the indicated part in the path
// get or create table array element at the indicated part in the path
keys, err := parseKey(key.val)
if err != nil {
p.raiseError(key, "invalid group array key: %s", err)
p.raiseError(key, "invalid table array key: %s", err)
}
p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries
destTree := p.tree.GetPath(keys)
@@ -111,32 +112,32 @@ func (p *tomlParser) parseGroupArray() tomlParserStateFn {
} else if target, ok := destTree.([]*TomlTree); ok && target != nil {
array = destTree.([]*TomlTree)
} else {
p.raiseError(key, "key %s is already assigned and not of type group array", key)
p.raiseError(key, "key %s is already assigned and not of type table array", key)
}
p.currentGroup = keys
p.currentTable = keys
// add a new tree to the end of the group array
// add a new tree to the end of the table array
newTree := newTomlTree()
newTree.position = startToken.Position
array = append(array, newTree)
p.tree.SetPath(p.currentGroup, array)
p.tree.SetPath(p.currentTable, array)
// remove all keys that were children of this group array
// remove all keys that were children of this table array
prefix := key.val + "."
found := false
for ii := 0; ii < len(p.seenGroupKeys); {
groupKey := p.seenGroupKeys[ii]
if strings.HasPrefix(groupKey, prefix) {
p.seenGroupKeys = append(p.seenGroupKeys[:ii], p.seenGroupKeys[ii+1:]...)
for ii := 0; ii < len(p.seenTableKeys); {
tableKey := p.seenTableKeys[ii]
if strings.HasPrefix(tableKey, prefix) {
p.seenTableKeys = append(p.seenTableKeys[:ii], p.seenTableKeys[ii+1:]...)
} else {
found = (groupKey == key.val)
found = (tableKey == key.val)
ii++
}
}
// keep this key name from use by other kinds of assignments
if !found {
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
p.seenTableKeys = append(p.seenTableKeys, key.val)
}
// move to next parser state
@@ -148,24 +149,24 @@ func (p *tomlParser) parseGroup() tomlParserStateFn {
startToken := p.getToken() // discard the [
key := p.getToken()
if key.typ != tokenKeyGroup {
p.raiseError(key, "unexpected token %s, was expecting a key group", key)
p.raiseError(key, "unexpected token %s, was expecting a table key", key)
}
for _, item := range p.seenGroupKeys {
for _, item := range p.seenTableKeys {
if item == key.val {
p.raiseError(key, "duplicated tables")
}
}
p.seenGroupKeys = append(p.seenGroupKeys, key.val)
p.seenTableKeys = append(p.seenTableKeys, key.val)
keys, err := parseKey(key.val)
if err != nil {
p.raiseError(key, "invalid group array key: %s", err)
p.raiseError(key, "invalid table array key: %s", err)
}
if err := p.tree.createSubTree(keys, startToken.Position); err != nil {
p.raiseError(key, "%s", err)
}
p.assume(tokenRightBracket)
p.currentGroup = keys
p.currentTable = keys
return p.parseStart
}
@@ -174,26 +175,26 @@ func (p *tomlParser) parseAssign() tomlParserStateFn {
p.assume(tokenEqual)
value := p.parseRvalue()
var groupKey []string
if len(p.currentGroup) > 0 {
groupKey = p.currentGroup
var tableKey []string
if len(p.currentTable) > 0 {
tableKey = p.currentTable
} else {
groupKey = []string{}
tableKey = []string{}
}
// find the group to assign, looking out for arrays of groups
// find the table to assign, looking out for arrays of tables
var targetNode *TomlTree
switch node := p.tree.GetPath(groupKey).(type) {
switch node := p.tree.GetPath(tableKey).(type) {
case []*TomlTree:
targetNode = node[len(node)-1]
case *TomlTree:
targetNode = node
default:
p.raiseError(key, "Unknown group type for path: %s",
strings.Join(groupKey, "."))
p.raiseError(key, "Unknown table type for path: %s",
strings.Join(tableKey, "."))
}
// assign value to the found group
// assign value to the found table
keyVals, err := parseKey(key.val)
if err != nil {
p.raiseError(key, "%s", err)
@@ -203,7 +204,7 @@ func (p *tomlParser) parseAssign() tomlParserStateFn {
}
keyVal := keyVals[0]
localKey := []string{keyVal}
finalKey := append(groupKey, keyVal)
finalKey := append(tableKey, keyVal)
if targetNode.GetPath(localKey) != nil {
p.raiseError(key, "The following key was defined twice: %s",
strings.Join(finalKey, "."))
@@ -224,7 +225,7 @@ var numberUnderscoreInvalidRegexp *regexp.Regexp
func cleanupNumberToken(value string) (string, error) {
if numberUnderscoreInvalidRegexp.MatchString(value) {
return "", fmt.Errorf("invalid use of _ in number")
return "", errors.New("invalid use of _ in number")
}
cleanedVal := strings.Replace(value, "_", "", -1)
return cleanedVal, nil
@@ -380,8 +381,8 @@ func parseToml(flow chan token) *TomlTree {
flow: flow,
tree: result,
tokensBuffer: make([]token, 0),
currentGroup: make([]string, 0),
seenGroupKeys: make([]string, 0),
currentTable: make([]string, 0),
seenTableKeys: make([]string, 0),
}
parser.run()
return result
+6 -6
View File
@@ -456,7 +456,7 @@ func TestDuplicateKeys(t *testing.T) {
func TestEmptyIntermediateTable(t *testing.T) {
_, err := Load("[foo..bar]")
if err.Error() != "(1, 2): invalid group array key: empty key group" {
if err.Error() != "(1, 2): invalid table array key: empty table key" {
t.Error("Bad error message:", err.Error())
}
}
@@ -580,12 +580,12 @@ func TestParseKeyGroupArray(t *testing.T) {
func TestParseKeyGroupArrayUnfinished(t *testing.T) {
_, err := Load("[[foo.bar]\na = 42")
if err.Error() != "(1, 10): was expecting token [[, but got unclosed key group array instead" {
if err.Error() != "(1, 10): was expecting token [[, but got unclosed table array key instead" {
t.Error("Bad error message:", err.Error())
}
_, err = Load("[[foo.[bar]\na = 42")
if err.Error() != "(1, 3): unexpected token group name cannot contain ']', was expecting a key group array" {
if err.Error() != "(1, 3): unexpected token table array key cannot contain ']', was expecting a table array key" {
t.Error("Bad error message:", err.Error())
}
}
@@ -753,13 +753,13 @@ func TestNestedTreePosition(t *testing.T) {
}
func TestInvalidGroupArray(t *testing.T) {
_, err := Load("[key#group]\nanswer = 42")
_, err := Load("[table#key]\nanswer = 42")
if err == nil {
t.Error("Should error")
}
_, err = Load("[foo.[bar]\na = 42")
if err.Error() != "(1, 2): unexpected token group name cannot contain ']', was expecting a key group" {
if err.Error() != "(1, 2): unexpected token table key cannot contain ']', was expecting a table key" {
t.Error("Bad error message:", err.Error())
}
}
@@ -773,7 +773,7 @@ func TestDoubleEqual(t *testing.T) {
func TestGroupArrayReassign(t *testing.T) {
_, err := Load("[hello]\n[[hello]]")
if err.Error() != "(2, 3): key \"hello\" is already assigned and not of type group array" {
if err.Error() != "(2, 3): key \"hello\" is already assigned and not of type table array" {
t.Error("Bad error message:", err.Error())
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ func toTomlValue(item interface{}, indent int) string {
}
// Recursive support function for ToString()
// Outputs a tree, using the provided keyspace to prefix group names
// Outputs a tree, using the provided keyspace to prefix table names
func (t *TomlTree) toToml(indent, keyspace string) string {
resultChunks := []string{}
for k, v := range t.values {
+6 -7
View File
@@ -2,9 +2,9 @@ package toml
import (
"reflect"
"strings"
"testing"
"time"
"strings"
)
func TestTomlTreeConversionToString(t *testing.T) {
@@ -47,15 +47,14 @@ func TestTomlTreeConversionToStringKeysOrders(t *testing.T) {
r := strings.NewReader(stringRepr)
toml, err := LoadReader(r)
if err != nil {
t.Fatal("Unexpected error:", err)
}
assertTree(t, toml, err, map[string]interface{}{
"foobar": true,
"bar": "baz",
"foo": 1,
"bar": "baz",
"foo": 1,
"qux": map[string]interface{}{
"foo": 1,
"bar": "baz2",
@@ -151,15 +150,15 @@ func TestTomlTreeConversionToMapWithArrayOfInlineTables(t *testing.T) {
"params": map[string]interface{}{
"language_tabs": []interface{}{
map[string]interface{}{
"key": "shell",
"key": "shell",
"name": "Shell",
},
map[string]interface{}{
"key": "ruby",
"key": "ruby",
"name": "Ruby",
},
map[string]interface{}{
"key": "python",
"key": "python",
"name": "Python",
},
},