From 03a3256e9c62e38f2b35fa83c35be06fe2123fd2 Mon Sep 17 00:00:00 2001 From: Jakob Strobl Date: Fri, 28 Aug 2020 18:51:06 -0400 Subject: fix(std/encoding/toml): Comment after arrays causing incorrect output (#7224) --- std/encoding/testdata/arrays.toml | 4 +- std/encoding/testdata/comment.toml | 29 +++++++++++ std/encoding/toml.ts | 100 ++++++++++++++++++++++++++----------- std/encoding/toml_test.ts | 27 ++++++++++ 4 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 std/encoding/testdata/comment.toml (limited to 'std/encoding') diff --git a/std/encoding/testdata/arrays.toml b/std/encoding/testdata/arrays.toml index 5d5913d0c..f52509bf2 100644 --- a/std/encoding/testdata/arrays.toml +++ b/std/encoding/testdata/arrays.toml @@ -1,8 +1,8 @@ [arrays] -data = [ ["gamma", "delta"], [1, 2] ] +data = [ ["gamma", "delta"], [1, 2] ] # comment after an array caused issue #7072 # Line breaks are OK when inside arrays hosts = [ "alpha", "omega" -] +] # comment \ No newline at end of file diff --git a/std/encoding/testdata/comment.toml b/std/encoding/testdata/comment.toml new file mode 100644 index 000000000..6bc9be045 --- /dev/null +++ b/std/encoding/testdata/comment.toml @@ -0,0 +1,29 @@ +# This is a full-line comment +str0 = 'value' # This is a comment at the end of a line +str1 = "# This is not a comment" # but this is +str2 = """ # this is not a comment! +A multiline string with a # +# this is also not a comment +""" # this is definitely a comment + +str3 = ''' +"# not a comment" + # this is a real tab on purpose +# not a comment +''' # comment + +point0 = { x = 1, y = 2, str0 = "#not a comment", z = 3 } # comment +point1 = { x = 7, y = 8, z = 9, str0 = "#not a comment"} # comment + +[deno] # this comment is fine +features = ["#secure by default", "supports typescript # not a comment"] # Comment caused Issue #7072 +url = "https://deno.land/" # comment +is_not_node = true # comment + +[toml] # Comment caused Issue #7072 (case 2) +name = "Tom's Obvious, Minimal Language" +objectives = [ # Comment + "easy to read", # Comment + "minimal config file", + "#not a comment" # comment +] # comment diff --git a/std/encoding/toml.ts b/std/encoding/toml.ts index 212c14bdc..62acc7db7 100644 --- a/std/encoding/toml.ts +++ b/std/encoding/toml.ts @@ -32,14 +32,82 @@ class Parser { for (let i = 0; i < this.tomlLines.length; i++) { const s = this.tomlLines[i]; const trimmed = s.trim(); - if (trimmed !== "" && trimmed[0] !== "#") { + if (trimmed !== "") { out.push(s); } } this.tomlLines = out; + this._removeComments(); this._mergeMultilines(); } + _removeComments(): void { + function isFullLineComment(line: string) { + return line.match(/^#/) ? true : false; + } + + function stringStart(line: string) { + const m = line.match(/(?:=\s*\[?\s*)("""|'''|"|')/); + if (!m) { + return false; + } + + // We want to know which syntax was used to open the string + openStringSyntax = m[1]; + return true; + } + + function stringEnd(line: string) { + // match the syntax used to open the string when searching for string close + // e.g. if we open with ''' we must close with a ''' + const reg = RegExp(`(? { + const expected = { + str0: "value", + str1: "# This is not a comment", + str2: + " # this is not a comment!\nA multiline string with a #\n# this is also not a comment", + str3: + '"# not a comment"\n\t# this is a real tab on purpose \n# not a comment', + point0: { x: 1, y: 2, str0: "#not a comment", z: 3 }, + point1: { x: 7, y: 8, z: 9, str0: "#not a comment" }, + deno: { + features: ["#secure by default", "supports typescript # not a comment"], + url: "https://deno.land/", + is_not_node: true, + }, + toml: { + name: "Tom's Obvious, Minimal Language", + objectives: ["easy to read", "minimal config file", "#not a comment"], + }, + }; + const actual = parseFile(path.join(testFilesDir, "comment.toml")); + assertEquals(actual, expected); + }, +}); -- cgit v1.2.3