Skip to content

Commit 08fbe61

Browse files
authored
toml: add compliance up until official toml-lang/toml-test@c6a78f1 (#26067)
1 parent 8aa0369 commit 08fbe61

3 files changed

Lines changed: 51 additions & 15 deletions

File tree

‎.github/workflows/download_full_toml_test_suites.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ rm -rf vlib/toml/tests/testdata/iarna vlib/toml/tests/testdata/toml_rs vlib/toml
1010
git -C vlib/toml/tests/testdata/iarna checkout 1880b1a
1111

1212
./v retry -- git clone -n https://github.com/toml-lang/toml-test.git vlib/toml/tests/testdata/toml_lang
13-
git -C vlib/toml/tests/testdata/toml_lang checkout f30c716
13+
git -C vlib/toml/tests/testdata/toml_lang checkout c6a78f1
1414

1515
# A few history notes of toml-rs (previously alexcrichton):
1616
# commit 7f5472c the test-suite dir moves to the crates/ sub-directory

‎vlib/toml/parser/parser.v‎

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ mut:
5959
// The root map (map is called table in TOML world)
6060
root_map map[string]ast.Value
6161
root_map_key DottedKey
62+
value_is_immutable bool
63+
immutable []DottedKey
6264
explicit_declared []DottedKey
6365
explicit_declared_array_of_tables []DottedKey
6466
implicit_declared []DottedKey
@@ -276,6 +278,14 @@ fn todo_msvc_astring2dkey(s []string) DottedKey {
276278
return s
277279
}
278280

281+
// check_immutable returns an error if `key` has been declared as immutable.
282+
fn (p &Parser) check_immutable(key DottedKey) ! {
283+
if p.immutable.len > 0 && p.immutable.has(key) {
284+
return error(@MOD + '.' + @STRUCT + '.' + @FN +
285+
' key `${key.str()}` is immutable. Unexpected mutation at "${p.tok.kind}" "${p.tok.lit}" in this (excerpt): "...${p.excerpt()}..."')
286+
}
287+
}
288+
279289
// check_explicitly_declared returns an error if `key` has been explicitly declared.
280290
fn (p &Parser) check_explicitly_declared(key DottedKey) ! {
281291
if p.explicit_declared.len > 0 && p.explicit_declared.has(key) {
@@ -612,6 +622,15 @@ pub fn (mut p Parser) root_table() ! {
612622
continue
613623
}
614624

625+
// Disallow mutation of immutable values (inline tables)
626+
if dotted_key.len > 1 {
627+
for part in dotted_key {
628+
dotted_part := DottedKey([part])
629+
if p.explicit_declared.has(dotted_part) {
630+
p.check_immutable(dotted_part)!
631+
}
632+
}
633+
}
615634
// Disallow re-declaring the key
616635
p.check_explicitly_declared(dotted_key)!
617636
p.explicit_declared << dotted_key
@@ -740,7 +759,7 @@ pub fn (mut p Parser) table_contents(mut tbl map[string]ast.Value) ! {
740759
// The V map type is corresponding to a "table" in TOML.
741760
pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! {
742761
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing inline table into ${ptr_str(tbl)}...')
743-
762+
defer { p.value_is_immutable = true }
744763
mut previous_token_was_value := false
745764
for p.tok.kind != .eof {
746765
p.next()!
@@ -786,8 +805,15 @@ pub fn (mut p Parser) inline_table(mut tbl map[string]ast.Value) ! {
786805
dotted_key, val := p.dotted_key_value()!
787806

788807
sub_table, key := p.sub_table_key(dotted_key)
789-
790808
mut t := p.find_in_table(mut tbl, sub_table)!
809+
810+
// Disallow mutation of immutable values (inline tables)
811+
if p.explicit_declared.has(dotted_key) {
812+
left_most := DottedKey([dotted_key[0]])
813+
if t.len > 0 {
814+
p.check_immutable(left_most)!
815+
}
816+
}
791817
unsafe {
792818
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'inserting @6 "${key}" = ${val} into ${ptr_str(t)}')
793819
t[key.str()] = val
@@ -907,13 +933,16 @@ pub fn (mut p Parser) double_array_of_tables(mut table map[string]ast.Value) ! {
907933

908934
p.check_explicitly_declared(dotted_key)!
909935

936+
first := DottedKey([dotted_key[0]]) // The array that holds the entries
937+
last := DottedKey([dotted_key[1]]) // The key the parsed array data should be added to
938+
939+
// Disallow re-declaring last part
940+
p.check_explicitly_declared(last)!
941+
910942
if !p.explicit_declared_array_of_tables.has(dotted_key) {
911943
p.explicit_declared_array_of_tables << dotted_key
912944
}
913945

914-
first := DottedKey([dotted_key[0]]) // The array that holds the entries
915-
last := DottedKey([dotted_key[1]]) // The key the parsed array data should be added to
916-
917946
mut t_arr := &[]ast.Value(unsafe { nil })
918947
mut t_map := ast.Value(ast.Null{})
919948

@@ -1245,17 +1274,20 @@ pub fn (mut p Parser) key() !ast.Key {
12451274
pub fn (mut p Parser) key_value() !(ast.Key, ast.Value) {
12461275
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing key value pair...')
12471276
key := p.key()!
1277+
dotted_key := DottedKey([key.str()])
1278+
p.explicit_declared << p.build_abs_dotted_key(dotted_key)
12481279
p.next()!
12491280
p.ignore_while(space_formatting)
12501281
p.check(.assign)! // Assignment operator
12511282
p.ignore_while(space_formatting)
12521283
value := p.value()!
1284+
if p.value_is_immutable {
1285+
if !p.immutable.has(dotted_key) {
1286+
p.immutable << p.build_abs_dotted_key(dotted_key) // Mark the key we are assigning to as immutable
1287+
}
1288+
p.value_is_immutable = false
1289+
}
12531290
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed key value pair. `${key} = ${value}`')
1254-
1255-
p.explicit_declared << p.build_abs_dotted_key(DottedKey([
1256-
key.str(),
1257-
]))
1258-
12591291
return key, value
12601292
}
12611293

@@ -1265,14 +1297,19 @@ pub fn (mut p Parser) dotted_key_value() !(DottedKey, ast.Value) {
12651297
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing dotted key value pair...')
12661298
p.ignore_while(space_formatting)
12671299
dotted_key := p.dotted_key()!
1300+
p.explicit_declared << p.build_abs_dotted_key(dotted_key)
12681301
p.ignore_while(space_formatting)
12691302
p.check(.assign)!
12701303
p.ignore_while(space_formatting)
12711304
value := p.value()!
1305+
if p.value_is_immutable {
1306+
if !p.immutable.has(dotted_key) {
1307+
p.immutable << p.build_abs_dotted_key(dotted_key) // Mark the key we are assigning to as immutable
1308+
}
1309+
p.value_is_immutable = false
1310+
}
12721311
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsed dotted key value pair `${dotted_key} = ${value}`...')
12731312

1274-
p.explicit_declared << p.build_abs_dotted_key(dotted_key)
1275-
12761313
return dotted_key, value
12771314
}
12781315

@@ -1281,7 +1318,6 @@ pub fn (mut p Parser) dotted_key_value() !(DottedKey, ast.Value) {
12811318
pub fn (mut p Parser) value() !ast.Value {
12821319
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'parsing value from token "${p.tok.kind}" "${p.tok.lit}"...')
12831320
mut value := ast.Value(ast.Null{})
1284-
12851321
if p.tok.kind == .number {
12861322
number_or_date := p.number_or_date()!
12871323
value = number_or_date

‎vlib/toml/tests/toml_lang_test.v‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Instructions for developers:
22
// The actual tests and data can be obtained by doing:
33
// `git clone -n https://github.com/toml-lang/toml-test.git vlib/toml/tests/testdata/toml_lang`
4-
// `git -C vlib/toml/tests/testdata/toml_lang reset --hard f30c716
4+
// `git -C vlib/toml/tests/testdata/toml_lang reset --hard c6a78f1
55
// See also the CI toml tests
66
import os
77
import toml

0 commit comments

Comments
 (0)