From d5546bf8743388caaf82770e837b5ffec5003910 Mon Sep 17 00:00:00 2001 From: Filip Hracek Date: Tue, 28 Feb 2017 17:58:55 -0800 Subject: [PATCH] Allow quotes and newlines in string literal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows creating string literals like “hello ‘world’” and “””hello\nworld”””. --- lib/src/builders/expression.dart | 12 +++++++++++- test/builders/expression_test.dart | 26 ++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/lib/src/builders/expression.dart b/lib/src/builders/expression.dart index 4565cb4..24d0f62 100644 --- a/lib/src/builders/expression.dart +++ b/lib/src/builders/expression.dart @@ -84,7 +84,7 @@ Literal _literal(value) { } else if (value is bool) { return value ? _true : _false; } else if (value is String) { - return astFactory.simpleStringLiteral(stringToken("'$value'"), value); + return astFactory.simpleStringLiteral(stringToken(_quote(value)), value); } else if (value is int) { return astFactory.integerLiteral(stringToken('$value'), value); } else if (value is double) { @@ -93,6 +93,16 @@ Literal _literal(value) { throw new ArgumentError.value(value, 'Unsupported'); } +/// Quotes the string literal. It is assumed that the [value] is meant to be +/// the raw string, so all `\` are escaped. +String _quote(String value) { + value = value.replaceAll(r'\', r'\\').replaceAll(r"'", r"\'"); + if (value.contains('\n')) { + return "'''$value'''"; + } + return "'$value'"; +} + /// Implements much of [ExpressionBuilder]. abstract class AbstractExpressionMixin implements ExpressionBuilder { @override diff --git a/test/builders/expression_test.dart b/test/builders/expression_test.dart index 21a4876..6467d4b 100644 --- a/test/builders/expression_test.dart +++ b/test/builders/expression_test.dart @@ -29,8 +29,30 @@ void main() { expect(literal(5.5), equalsSource(r'5.5')); }); - test('should emit a string', () { - expect(literal('Hello'), equalsSource(r"'Hello'")); + group('should emit a string', () { + test('simple', () { + expect(literal('Hello'), equalsSource(r"'Hello'")); + }); + + test("with a '", () { + expect(literal("Hello'"), equalsSource(r"'Hello\''")); + }); + + test(r"with a \'", () { + expect(literal(r"Hello\'"), equalsSource(r"'Hello\\\''")); + }); + + test(r"with a \\'", () { + expect(literal(r"Hello\\'"), equalsSource(r"'Hello\\\\\''")); + }); + + test(r"with a newline", () { + expect(literal("Hello\nworld"), equalsSource("'''Hello\nworld'''")); + }); + + test(r"with a newline and ending with a '", () { + expect(literal("Hello\nworld'"), equalsSource("'''Hello\nworld\\''''")); + }); }); test('should emit a list', () {