From f3f9d3413e6fb8b141d313552102ede309e1e450 Mon Sep 17 00:00:00 2001 From: Alfonso Garcia-Caro Date: Wed, 15 Jun 2022 12:10:34 +0900 Subject: [PATCH] Add some tests --- src/Compiler/Service/ServiceLexing.fs | 2 +- .../Compiler/Language/StringInterpolation.fs | 21 ++++ tests/service/TokenizerTests.fs | 105 +++++++++++++++++- 3 files changed, 122 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index 34d9210a315..532c68f25e3 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -615,7 +615,7 @@ module internal LexerStateEncoding = match stringNest with | [] -> false, 0, 0, false, [] | (i1, kind1, b1, _)::rest -> true, i1, encodeStringStyle kind1, b1, rest - + let tag2, i2, kind2, b2 = match rest with | [] -> false, 0, 0, false diff --git a/tests/fsharp/Compiler/Language/StringInterpolation.fs b/tests/fsharp/Compiler/Language/StringInterpolation.fs index 708d9be5e3b..c0f9678da17 100644 --- a/tests/fsharp/Compiler/Language/StringInterpolation.fs +++ b/tests/fsharp/Compiler/Language/StringInterpolation.fs @@ -463,6 +463,16 @@ check "vcewweh228d" "{{" "{{" check "vcewweh229f" "}}" "}}" """ + [] + let ``String interpolation using escaped braces - double dollar`` () = + SimpleCheckTest + """ +check "vcewweh226i" $$"{" "{" +check "vcewweh226f" $$"{}" "{}" +check "vcewweh226p" $$"{ {{1}} }" "{ 1 }" +check "vcewweh227a" $$"}}" "}" + """ + [] let ``String interpolation using verbatim strings`` () = SimpleCheckTest @@ -487,11 +497,19 @@ type R2 = { X : int ; Y: int } // Check record expression (parenthesized) check "vcewweh18" $"abc{({contents=1}.contents)}def" "abc1def" +// Check record expression (parenthesized) - double dollar +check "vcewweh18b" $$"abc{{({contents=1}.contents)}}def" "abc1def" + // Check record expression (unparenthesized, spaced) check "vcewweh19a" $"abc{ {X=1} }def" "abc{ X = 1 }def" check "vcewweh19b" $"abc{ {X=1} }def" "abc{ X = 1 }def" +// Check record expression (unparenthesized, spaced) - double dollar +check "vcewweh19c" $$"abc{{ {X=1} }}def" "abc{ X = 1 }def" + +check "vcewweh19d" $$"abc{{ {X=1} }}def" "abc{ X = 1 }def" + // Check record expression (unparenthesized, spaced ending in token brace then string hole brace) check "vcewweh19v" $"abc{ {X=1}}def" "abc{ X = 1 }def" @@ -501,6 +519,9 @@ check "vcewweh20" $"abc{{X=1}}def" "abc{X=1}def" // Check thing that is not really a record expression (braces are escaped) check "vcewweh20b" $"abc{{quack=1}}def" "abc{quack=1}def" +// Check thing that is not really a record expression (double dollar) +check "vcewweh20c" $$"abc{X=1}def" "abc{X=1}def" + // Check thing that is not really a record expression (braces are escaped) check "vcewweh21" $"abc{{X=1; Y=2}}def" "abc{X=1; Y=2}def" diff --git a/tests/service/TokenizerTests.fs b/tests/service/TokenizerTests.fs index 8b0fc2c8995..a951748b3d0 100644 --- a/tests/service/TokenizerTests.fs +++ b/tests/service/TokenizerTests.fs @@ -66,9 +66,11 @@ let ``Tokenizer test 2 - single line non-nested string interpolation``() = "let hello0 = $\"\"" "let hello1 = $\"Hello world\" " "let hello2 = $\"Hello world {1+1} = {2}\" " + "let hello3 = $$\"Hello world {{1+1}} = {{2}}\" " "let hello0v = @$\"\"" "let hello1v = @$\"Hello world\" " - "let hello2v = @$\"Hello world {1+1} = {2}\" " |] + "let hello2v = @$\"Hello world {1+1} = {2}\" " + "let hello3v = @$\"Hello world {{1+1}} = {{2}}\" " |] let actual = [ for lineNo, lineToks in tokenizedLines do @@ -98,16 +100,25 @@ let ``Tokenizer test 2 - single line non-nested string interpolation``() = ("INTERP_STRING_PART", "{"); ("INT32", "2"); ("STRING_TEXT", "}"); ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")]); (4, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello3"); ("WHITESPACE", " "); + ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "$$\""); + ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); ("STRING_TEXT", "world"); + ("STRING_TEXT", " "); ("INTERP_STRING_BEGIN_PART", "{{"); ("INT32", "1"); + ("PLUS_MINUS_OP", "+"); ("INT32", "1"); ("STRING_TEXT", "}}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "="); ("STRING_TEXT", " "); + ("INTERP_STRING_PART", "{{"); ("INT32", "2"); ("STRING_TEXT", "}}"); + ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")]); + (5, [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello0v"); ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); - ("STRING_TEXT", "@$\""); ("INTERP_STRING_BEGIN_END", "\"")]); - (5, + ("STRING_TEXT", "@$$\""); ("INTERP_STRING_BEGIN_END", "\"")]); + (6, [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1v"); ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "@$\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); ("STRING_TEXT", "world"); ("INTERP_STRING_BEGIN_END", "\""); ("WHITESPACE", " ")]); - (6, + (7, [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello2v"); ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); ("STRING_TEXT", "@$\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); @@ -116,6 +127,16 @@ let ``Tokenizer test 2 - single line non-nested string interpolation``() = ("INT32", "1"); ("STRING_TEXT", "}"); ("STRING_TEXT", " "); ("STRING_TEXT", "="); ("STRING_TEXT", " "); ("INTERP_STRING_PART", "{"); ("INT32", "2"); ("STRING_TEXT", "}"); ("INTERP_STRING_END", "\""); + ("WHITESPACE", " ")]); + (8, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello3v"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "@$$\""); ("STRING_TEXT", "Hello"); ("STRING_TEXT", " "); + ("STRING_TEXT", "world"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{{"); ("INT32", "1"); ("PLUS_MINUS_OP", "+"); + ("INT32", "1"); ("STRING_TEXT", "}}"); ("STRING_TEXT", " "); + ("STRING_TEXT", "="); ("STRING_TEXT", " "); ("INTERP_STRING_PART", "{{"); + ("INT32", "2"); ("STRING_TEXT", "}}"); ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")]);] if actual <> expected then @@ -129,7 +150,9 @@ let ``Tokenizer test - multiline non-nested string interpolation``() = let tokenizedLines = tokenizeLines [| "let hello1t = $\"\"\"abc {1+" - " 1} def\"\"\"" |] + " 1} def\"\"\"" + "let hello2t = $$\"\"\"abc {{1+" + " 1}} def\"\"\"" |] let actual = [ for lineNo, lineToks in tokenizedLines do @@ -142,6 +165,14 @@ let ``Tokenizer test - multiline non-nested string interpolation``() = ("INTERP_STRING_BEGIN_PART", "{"); ("INT32", "1"); ("PLUS_MINUS_OP", "+")]); (1, [("WHITESPACE", " "); ("INT32", "1"); ("STRING_TEXT", "}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "def"); ("INTERP_STRING_END", "\"\"\"")]) + (2, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1t"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "$$\"\"\""); ("STRING_TEXT", "abc"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{{"); ("INT32", "1"); ("PLUS_MINUS_OP", "+")]); + (3, + [("WHITESPACE", " "); ("INT32", "1"); ("STRING_TEXT", "}}"); ("STRING_TEXT", " "); ("STRING_TEXT", "def"); ("INTERP_STRING_END", "\"\"\"")])] if actual <> expected then @@ -191,6 +222,48 @@ let ``Tokenizer test - multi-line nested string interpolation``() = printfn "expected = %A" expected Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) +[] +// checks nested '{' and nested single-quote strings +let ``Tokenizer test - multi-line nested string interpolation - double dollar``() = + let tokenizedLines = + tokenizeLines + [| "let hello1t = $$\"\"\"abc {{\"a\" + " + " { " + " contents = \"b\" " + " }.contents " + " }} def\"\"\"" |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("LET", "let"); ("WHITESPACE", " "); ("IDENT", "hello1t"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "$$\"\"\""); ("STRING_TEXT", "abc"); ("STRING_TEXT", " "); + ("INTERP_STRING_BEGIN_PART", "{{"); ("STRING_TEXT", "\""); ("STRING_TEXT", "a"); + ("STRING", "\""); ("WHITESPACE", " "); ("PLUS_MINUS_OP", "+"); + ("WHITESPACE", " ")]); + (1, + [("WHITESPACE", " "); ("LBRACE", "{"); + ("WHITESPACE", " ")]); + (2, + [("WHITESPACE", " "); ("IDENT", "contents"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); + ("STRING_TEXT", "\""); ("STRING_TEXT", "b"); ("STRING", "\""); + ("WHITESPACE", " ")]); + (3, + [("WHITESPACE", " "); ("RBRACE", "}"); ("DOT", "."); + ("IDENT", "contents"); ("WHITESPACE", " ")]); + (4, + [("WHITESPACE", " "); ("STRING_TEXT", "}}"); + ("STRING_TEXT", " "); ("STRING_TEXT", "def"); ("INTERP_STRING_END", "\"\"\"")])] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) + [] let ``Tokenizer test - single-line nested string interpolation``() = let tokenizedLines = @@ -214,3 +287,25 @@ let ``Tokenizer test - single-line nested string interpolation``() = printfn "expected = %A" expected Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected) +[] +let ``Tokenizer test - single-line nested string interpolation - double dollar``() = + let tokenizedLines = + tokenizeLines + [| " $$\"abc {{ { contents = 1 } }}\" " |] + + let actual = + [ for lineNo, lineToks in tokenizedLines do + yield lineNo, [ for str, info in lineToks do yield info.TokenName, str ] ] + let expected = + [(0, + [("WHITESPACE", " "); ("STRING_TEXT", "$$\""); ("STRING_TEXT", "abc"); + ("STRING_TEXT", " "); ("INTERP_STRING_BEGIN_PART", "{{"); ("WHITESPACE", " "); + ("LBRACE", "{"); ("WHITESPACE", " "); ("IDENT", "contents"); + ("WHITESPACE", " "); ("EQUALS", "="); ("WHITESPACE", " "); ("INT32", "1"); + ("WHITESPACE", " "); ("RBRACE", "}"); ("WHITESPACE", " "); + ("STRING_TEXT", "}}"); ("INTERP_STRING_END", "\""); ("WHITESPACE", " ")])] + + if actual <> expected then + printfn "actual = %A" actual + printfn "expected = %A" expected + Assert.Fail(sprintf "actual and expected did not match,actual =\n%A\nexpected=\n%A\n" actual expected)