Commit e1370357cc6a01166c099d5df2142395ca21dc70

Michael Schmidt 2021-11-22T13:32:11

Dart: Added string interpolation and improved metadata (#3197)

diff --git a/components/prism-dart.js b/components/prism-dart.js
index 564f921..e35e38a 100644
--- a/components/prism-dart.js
+++ b/components/prism-dart.js
@@ -22,16 +22,6 @@
 	};
 
 	Prism.languages.dart = Prism.languages.extend('clike', {
-		'string': [
-			{
-				pattern: /r?("""|''')[\s\S]*?\1/,
-				greedy: true
-			},
-			{
-				pattern: /r?(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,
-				greedy: true
-			}
-		],
 		'class-name': [
 			className,
 			{
@@ -46,10 +36,32 @@
 		'operator': /\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/
 	});
 
-	Prism.languages.insertBefore('dart', 'function', {
+	Prism.languages.insertBefore('dart', 'string', {
+		'string-literal': {
+			pattern: /r?(?:("""|''')[\s\S]*?\1|(["'])(?:\\.|(?!\2)[^\\\r\n])*\2(?!\2))/,
+			greedy: true,
+			inside: {
+				'interpolation': {
+					pattern: /((?:^|[^\\])(?:\\{2})*)\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,
+					lookbehind: true,
+					inside: {
+						'punctuation': /^\$\{?|\}$/,
+						'expression': {
+							pattern: /[\s\S]+/,
+							inside: Prism.languages.dart
+						}
+					}
+				},
+				'string': /[\s\S]+/
+			}
+		},
+		'string': undefined
+	});
+
+	Prism.languages.insertBefore('dart', 'class-name', {
 		'metadata': {
 			pattern: /@\w+/,
-			alias: 'symbol'
+			alias: 'function'
 		}
 	});
 
diff --git a/components/prism-dart.min.js b/components/prism-dart.min.js
index 833c7e1..e16ca21 100644
--- a/components/prism-dart.min.js
+++ b/components/prism-dart.min.js
@@ -1 +1 @@
-!function(e){var a=[/\b(?:async|sync|yield)\*/,/\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extends|extension|external|factory|final|finally|for|get|hide|if|implements|import|in|interface|library|mixin|new|null|on|operator|part|rethrow|return|set|show|static|super|switch|sync|this|throw|try|typedef|var|void|while|with|yield)\b/],t="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp(t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}}}};e.languages.dart=e.languages.extend("clike",{string:[{pattern:/r?("""|''')[\s\S]*?\1/,greedy:!0},{pattern:/r?(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0}],"class-name":[s,{pattern:RegExp(t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()])"),lookbehind:!0,inside:s.inside}],keyword:a,operator:/\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/}),e.languages.insertBefore("dart","function",{metadata:{pattern:/@\w+/,alias:"symbol"}}),e.languages.insertBefore("dart","class-name",{generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":s,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}}})}(Prism);
\ No newline at end of file
+!function(e){var a=[/\b(?:async|sync|yield)\*/,/\b(?:abstract|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extends|extension|external|factory|final|finally|for|get|hide|if|implements|import|in|interface|library|mixin|new|null|on|operator|part|rethrow|return|set|show|static|super|switch|sync|this|throw|try|typedef|var|void|while|with|yield)\b/],n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}}}};e.languages.dart=e.languages.extend("clike",{"class-name":[s,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()])"),lookbehind:!0,inside:s.inside}],keyword:a,operator:/\bis!|\b(?:as|is)\b|\+\+|--|&&|\|\||<<=?|>>=?|~(?:\/=?)?|[+\-*\/%&^|=!<>]=?|\?/}),e.languages.insertBefore("dart","string",{"string-literal":{pattern:/r?(?:("""|''')[\s\S]*?\1|(["'])(?:\\.|(?!\2)[^\\\r\n])*\2(?!\2))/,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,lookbehind:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:e.languages.dart}}},string:/[\s\S]+/}},string:void 0}),e.languages.insertBefore("dart","class-name",{metadata:{pattern:/@\w+/,alias:"function"}}),e.languages.insertBefore("dart","class-name",{generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":s,keyword:a,punctuation:/[<>(),.:]/,operator:/[?&|]/}}})}(Prism);
\ No newline at end of file
diff --git a/tests/languages/dart/metadata_feature.test b/tests/languages/dart/metadata_feature.test
index e88e7ba..2eecbac 100644
--- a/tests/languages/dart/metadata_feature.test
+++ b/tests/languages/dart/metadata_feature.test
@@ -1,20 +1,148 @@
 @deprecated
 @override
-@todo('seth', 'make this do something')
+@ToDo('seth', 'make this do something')
+
+@DataTable("sale_orders")
+class SaleOrder {
+  @DataColumn("sale_order_date")
+  DateTime date;
+}
+
+@table
+class Product {
+  @column
+  String name;
+}
+
+const DataColumn column = const DataColumn();
+
+const DataTable table = const DataTable();
+
+class DataTable {
+  final String name;
+
+  const DataTable([this.name]);
+}
+
+class DataColumn {
+  final String name;
+
+  const DataColumn([this.name]);
+}
 
 ----------------------------------------------------
 
 [
 	["metadata", "@deprecated"],
+
 	["metadata", "@override"],
-	["metadata", "@todo"],
+
+	["metadata", "@ToDo"],
 	["punctuation", "("],
-	["string", "'seth'"],
+	["string-literal", [
+		["string", "'seth'"]
+	]],
 	["punctuation", ","],
-	["string", "'make this do something'"],
-	["punctuation", ")"]
+	["string-literal", [
+		["string", "'make this do something'"]
+	]],
+	["punctuation", ")"],
+
+	["metadata", "@DataTable"],
+	["punctuation", "("],
+	["string-literal", [
+		["string", "\"sale_orders\""]
+	]],
+	["punctuation", ")"],
+
+	["keyword", "class"],
+	["class-name", ["SaleOrder"]],
+	["punctuation", "{"],
+
+	["metadata", "@DataColumn"],
+	["punctuation", "("],
+	["string-literal", [
+		["string", "\"sale_order_date\""]
+	]],
+	["punctuation", ")"],
+
+	["class-name", ["DateTime"]],
+	" date",
+	["punctuation", ";"],
+
+	["punctuation", "}"],
+
+	["metadata", "@table"],
+	["keyword", "class"], ["class-name", ["Product"]], ["punctuation", "{"],
+	["metadata", "@column"],
+	["class-name", ["String"]], " name", ["punctuation", ";"],
+	["punctuation", "}"],
+
+	["keyword", "const"],
+	["class-name", ["DataColumn"]],
+	" column ",
+	["operator", "="],
+	["keyword", "const"],
+	["class-name", ["DataColumn"]],
+	["punctuation", "("],
+	["punctuation", ")"],
+	["punctuation", ";"],
+
+	["keyword", "const"],
+	["class-name", ["DataTable"]],
+	" table ",
+	["operator", "="],
+	["keyword", "const"],
+	["class-name", ["DataTable"]],
+	["punctuation", "("],
+	["punctuation", ")"],
+	["punctuation", ";"],
+
+	["keyword", "class"],
+	["class-name", ["DataTable"]],
+	["punctuation", "{"],
+
+	["keyword", "final"],
+	["class-name", ["String"]],
+	" name",
+	["punctuation", ";"],
+
+	["keyword", "const"],
+	["class-name", ["DataTable"]],
+	["punctuation", "("],
+	["punctuation", "["],
+	["keyword", "this"],
+	["punctuation", "."],
+	"name",
+	["punctuation", "]"],
+	["punctuation", ")"],
+	["punctuation", ";"],
+
+	["punctuation", "}"],
+
+	["keyword", "class"],
+	["class-name", ["DataColumn"]],
+	["punctuation", "{"],
+
+	["keyword", "final"],
+	["class-name", ["String"]],
+	" name",
+	["punctuation", ";"],
+
+	["keyword", "const"],
+	["class-name", ["DataColumn"]],
+	["punctuation", "("],
+	["punctuation", "["],
+	["keyword", "this"],
+	["punctuation", "."],
+	"name",
+	["punctuation", "]"],
+	["punctuation", ")"],
+	["punctuation", ";"],
+
+	["punctuation", "}"]
 ]
 
 ----------------------------------------------------
 
-Checks for metadata.
\ No newline at end of file
+Checks for metadata.
diff --git a/tests/languages/dart/string_feature.test b/tests/languages/dart/string_feature.test
index feffdbc..951d9fe 100644
--- a/tests/languages/dart/string_feature.test
+++ b/tests/languages/dart/string_feature.test
@@ -8,18 +8,89 @@ bar"""
 '''foo
 bar'''
 
+'$string has ${string.length} letters'
+"cookie has ${cookie.number_of_chips} chips"
+
 ----------------------------------------------------
 
 [
-	["string", "\"\""], ["string", "''"],
-	["string", "r\"\""], ["string", "r''"],
-	["string", "\"\"\"\"\"\""], ["string", "''''''"],
-	["string", "r\"\"\"\"\"\""], ["string", "r''''''"],
-	["string", "\"fo\\\"o\""], ["string", "'fo\\'o'"],
-	["string", "\"\"\"foo\r\nbar\"\"\""], ["string", "'''foo\r\nbar'''"]
+	["string-literal", [
+		["string", "\"\""]
+	]],
+	["string-literal", [
+		["string", "''"]
+	]],
+
+	["string-literal", [
+		["string", "r\"\""]
+	]],
+	["string-literal", [
+		["string", "r''"]
+	]],
+
+	["string-literal", [
+		["string", "\"\"\"\"\"\""]
+	]],
+	["string-literal", [
+		["string", "''''''"]
+	]],
+
+	["string-literal", [
+		["string", "r\"\"\"\"\"\""]
+	]],
+	["string-literal", [
+		["string", "r''''''"]
+	]],
+
+	["string-literal", [
+		["string", "\"fo\\\"o\""]
+	]],
+	["string-literal", [
+		["string", "'fo\\'o'"]
+	]],
+
+	["string-literal", [
+		["string", "\"\"\"foo\r\nbar\"\"\""]
+	]],
+
+	["string-literal", [
+		["string", "'''foo\r\nbar'''"]
+	]],
+
+	["string-literal", [
+		["string", "'"],
+		["interpolation", [
+			["punctuation", "$"],
+			["expression", ["string"]]
+		]],
+		["string", " has "],
+		["interpolation", [
+			["punctuation", "${"],
+			["expression", [
+				"string",
+				["punctuation", "."],
+				"length"
+			]],
+			["punctuation", "}"]
+		]],
+		["string", " letters'"]
+	]],
+	["string-literal", [
+		["string", "\"cookie has "],
+		["interpolation", [
+			["punctuation", "${"],
+			["expression", [
+				"cookie",
+				["punctuation", "."],
+				"number_of_chips"
+			]],
+			["punctuation", "}"]
+		]],
+		["string", " chips\""]
+	]]
 ]
 
 ----------------------------------------------------
 
 Checks for single quoted and double quoted strings,
-multi-line strings and "raw" strings.
\ No newline at end of file
+multi-line strings and "raw" strings.