toml: support empty tables (#12504)

pull/12509/head
Larpon 2021-11-18 14:39:44 +01:00 committed by GitHub
parent 24ea15c8f0
commit 7fba3e65e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 26 deletions

View File

@ -254,10 +254,7 @@ fn (p Parser) check_explicitly_declared(key DottedKey) ? {
// See also `find_in_table`.
pub fn (mut p Parser) find_table() ?&map[string]ast.Value {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$p.root_map_key" in map ${ptr_str(p.root_map)}')
mut t := &map[string]ast.Value{}
unsafe {
t = &p.root_map
}
mut t := unsafe { &p.root_map }
if p.root_map_key.len == 0 {
return t
}
@ -265,6 +262,16 @@ pub fn (mut p Parser) find_table() ?&map[string]ast.Value {
return p.find_in_table(mut t, p.root_map_key)
}
// allocate_table allocates all tables in "dotted" `key` (`a.b.c`) in the *root* table.
pub fn (mut p Parser) allocate_table(key DottedKey) ? {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(p.root_map)}')
mut t := unsafe { &p.root_map }
if key.len == 0 {
return
}
p.allocate_in_table(mut t, key) ?
}
// sub_table_key returns the logic parts of a dotted key (`a.b.c`) for
// use with the `find_sub_table` method.
pub fn (mut p Parser) sub_table_key(key DottedKey) (DottedKey, DottedKey) {
@ -286,10 +293,7 @@ pub fn (mut p Parser) find_sub_table(key DottedKey) ?&map[string]ast.Value {
ky = key
}
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$ky" in map ${ptr_str(p.root_map)}')
mut t := &map[string]ast.Value{}
unsafe {
t = &p.root_map
}
mut t := unsafe { &p.root_map }
if ky.len == 0 {
return t
}
@ -306,10 +310,7 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe
// I'm still not quite sure *exactly* why it works. All I can leave here is a hope
// that this kind of minefield someday will be easier in V :)
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$key" in map ${ptr_str(table)}')
mut t := &map[string]ast.Value{}
unsafe {
t = &table
}
mut t := unsafe { &table }
unsafe {
for k in key {
if val := t[k] {
@ -332,6 +333,30 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe
return t
}
// allocate_in_table allocates all tables in "dotted" `key` (`a.b.c`) in `table`.
pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key DottedKey) ? {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(table)}')
mut t := unsafe { &table }
unsafe {
for k in key {
if val := t[k] {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'found key "$k" in $t.keys()')
if val is map[string]ast.Value {
t = &(val as map[string]ast.Value)
} else {
return error(@MOD + '.' + @STRUCT + '.' + @FN +
' "$k" in "$key" is not a map ($val.type_name())')
}
} else {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'no key "$k" in "$key" found, allocating new map at key "$k" in map ${ptr_str(t)}"')
t[k] = map[string]ast.Value{}
t = &(t[k] as map[string]ast.Value)
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocated new map ${ptr_str(t)}"')
}
}
}
}
// dotted_key returns a string of the next tokens parsed as
// sub/nested/path keys (e.g. `a.b.c`). In TOML, this form of key is referred to as a "dotted" key.
pub fn (mut p Parser) dotted_key() ?DottedKey {
@ -476,6 +501,7 @@ pub fn (mut p Parser) root_table() ? {
p.ignore_while(parser.space_formatting)
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
p.root_map_key = dotted_key
p.allocate_table(p.root_map_key) ?
p.expect(.rsbr) ?
p.peek_for_correct_line_ending_or_fail() ?
} else {
@ -497,6 +523,7 @@ pub fn (mut p Parser) root_table() ? {
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
p.root_map_key = dotted_key
p.allocate_table(p.root_map_key) ?
p.next() ?
p.expect(.rsbr) ?
p.peek_for_correct_line_ending_or_fail() ?
@ -822,10 +849,7 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a
} else {
key, val := p.key_value() ?
mut t := &map[string]ast.Value{}
unsafe {
t = &tbl
}
mut t := unsafe { &tbl }
if implicit_allocation_key.len > 0 {
t = p.find_in_table(mut tbl, implicit_allocation_key) ?
}

View File

@ -31,18 +31,8 @@ const (
// Comment
'comment/tricky.toml',
// Table
'table/empty.toml',
'table/array-implicit.toml',
'table/sub-empty.toml',
'table/without-super.toml',
'table/whitespace.toml',
'table/names.toml',
'table/no-eol.toml',
'table/keyword.toml',
// Array
'array/string-quote-comma.toml',
'array/string-quote-comma-2.toml',
'array/table-array-string-backslash.toml',
// Date-time
'datetime/milliseconds.toml',
// Inline-table