git.delta.rocks / jrsonnet / refs/commits / 2223f9ab687d

difftreelog

fix incorrect doccomment parsing

pyqrqpwvYaroslav Bolyukin2026-05-07parent: #3c251da.patch.diff
in: master

8 files changed

modifiedcrates/jrsonnet-lexer/src/generated/syntax_kinds.rsdiffbeforeafterboth
--- a/crates/jrsonnet-lexer/src/generated/syntax_kinds.rs
+++ b/crates/jrsonnet-lexer/src/generated/syntax_kinds.rs
@@ -128,7 +128,7 @@
 	SINGLE_LINE_SLASH_COMMENT,
 	#[regex("#[^\\r\\n]*?(\\r\\n|\\n)?")]
 	SINGLE_LINE_HASH_COMMENT,
-	#[regex("/\\*([^*]|\\*[^/])*\\*/")]
+	#[regex("/\\*([^*]|\\*+[^*/])*\\*+/")]
 	MULTI_LINE_COMMENT,
 	#[regex("/\\*/")]
 	ERROR_COMMENT_TOO_SHORT,
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_doc.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_doc.snap
@@ -0,0 +1,39 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "{ a:: 1, /** doc **/ b:: 2 }\n"
+---
+SOURCE_FILE@0..29
+  EXPR@0..28
+    EXPR_OBJECT@0..28
+      OBJ_BODY_MEMBER_LIST@0..28
+        L_BRACE@0..1 "{"
+        WHITESPACE@1..2 " "
+        MEMBER_FIELD_NORMAL@2..7
+          FIELD_NAME_FIXED@2..3
+            NAME@2..3
+              IDENT@2..3 "a"
+          VISIBILITY@3..5
+            COLON@3..4 ":"
+            COLON@4..5 ":"
+          WHITESPACE@5..6 " "
+          EXPR@6..7
+            EXPR_NUMBER@6..7
+              FLOAT@6..7 "1"
+        COMMA@7..8 ","
+        WHITESPACE@8..9 " "
+        MULTI_LINE_COMMENT@9..20 "/** doc **/"
+        WHITESPACE@20..21 " "
+        MEMBER_FIELD_NORMAL@21..26
+          FIELD_NAME_FIXED@21..22
+            NAME@21..22
+              IDENT@21..22 "b"
+          VISIBILITY@22..24
+            COLON@22..23 ":"
+            COLON@23..24 ":"
+          WHITESPACE@24..25 " "
+          EXPR@25..26
+            EXPR_NUMBER@25..26
+              FLOAT@25..26 "2"
+        WHITESPACE@26..27 " "
+        R_BRACE@27..28 "}"
+  WHITESPACE@28..29 "\n"
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_empty.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_empty.snap
@@ -0,0 +1,11 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "/**/ 1\n"
+---
+SOURCE_FILE@0..7
+  MULTI_LINE_COMMENT@0..4 "/**/"
+  WHITESPACE@4..5 " "
+  EXPR@5..6
+    EXPR_NUMBER@5..6
+      FLOAT@5..6 "1"
+  WHITESPACE@6..7 "\n"
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_inner_star.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_inner_star.snap
@@ -0,0 +1,11 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "/* * */ 3\n"
+---
+SOURCE_FILE@0..10
+  MULTI_LINE_COMMENT@0..7 "/* * */"
+  WHITESPACE@7..8 " "
+  EXPR@8..9
+    EXPR_NUMBER@8..9
+      FLOAT@8..9 "3"
+  WHITESPACE@9..10 "\n"
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_too_short.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_too_short.snap
@@ -0,0 +1,14 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "/*/\n"
+---
+SOURCE_FILE@0..4
+  ERROR_COMMENT_TOO_SHORT@0..3 "/*/"
+  WHITESPACE@3..4 "\n"
+  EXPR@4..4
+    ERROR_MISSING_TOKEN@4..4
+===
+LocatedSyntaxError { error: Missing { expected: Named("expression") }, range: 4..4 }
+===
+   ·     ╭── missing expression
+1  │ /*/
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_triple_star.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_triple_star.snap
@@ -0,0 +1,11 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "/***/ 2\n"
+---
+SOURCE_FILE@0..8
+  MULTI_LINE_COMMENT@0..5 "/***/"
+  WHITESPACE@5..6 " "
+  EXPR@6..7
+    EXPR_NUMBER@6..7
+      FLOAT@6..7 "2"
+  WHITESPACE@7..8 "\n"
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_unterminated.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__multi_line_comment_unterminated.snap
@@ -0,0 +1,13 @@
+---
+source: crates/jrsonnet-rowan-parser/src/tests.rs
+expression: "/** unterminated\n"
+---
+SOURCE_FILE@0..17
+  ERROR_COMMENT_UNTERMINATED@0..17 "/** unterminated\n"
+  EXPR@17..17
+    ERROR_MISSING_TOKEN@17..17
+===
+LocatedSyntaxError { error: Missing { expected: Named("expression") }, range: 17..17 }
+===
+   ·                  ╭── missing expression
+1  │ /** unterminated
modifiedcrates/jrsonnet-rowan-parser/src/tests.rsdiffbeforeafterboth
after · crates/jrsonnet-rowan-parser/src/tests.rs
1// `never`2#![cfg(test)]34use hi_doc::{Formatting, SnippetBuilder, Text};56use crate::{AstNode, parse};78fn process(text: &str) -> String {9	use std::fmt::Write;10	let mut out = String::new();11	let (node, errors) = parse(text);12	write!(out, "{:#?}", node.syntax()).unwrap();13	if !errors.is_empty() && !text.is_empty() {14		writeln!(out, "===").unwrap();15		for err in &errors {16			writeln!(out, "{err:?}").unwrap();17		}18		let mut code = text.to_string();1920		// Prettier errors at EOF position21		if code.ends_with('\n') {22			code.truncate(code.len() - 1);23			code += " ";24		}25		code += " ";2627		let mut s = SnippetBuilder::new(code);2829		for error in errors {30			s.error(Text::fragment(31				format!("{}", error.error),32				Formatting::default(),33			))34			.range(error.range.start().into()..=error.range.end().into())35			.build();36		}3738		writeln!(out, "===").unwrap();39		let ansi = hi_doc::source_to_ansi(&s.build());40		let text = strip_ansi_escapes::strip_str(&ansi);41		out.push_str(&text);42	}43	out.split('\n')44		.map(|s| s.trim_end().to_string())45		.collect::<Vec<String>>()46		.join("\n")47		.trim_end()48		.to_string()49}50macro_rules! mk_test {51		($($name:ident => $test:expr)+) => {$(52			#[test]53			fn $name() {54				let src = indoc::indoc!($test);55				let result = process(&src);56				insta::assert_snapshot!(stringify!($name), result, src);57			}58		)+};59	}60mk_test!(61	empty => r#" "#62	function => r#"63		function(a, b = 1) a + b64	"#65	function_error_no_value => r#"66		function(a, b = ) a + b67	"#68	function_error_rparen => r#"69		function(a, b70	"#71	function_error_body => r#"72		function(a, b)73	"#74	local_novalue => r#"75		local a =76	"#77	local_no_value_recovery => r#"78		local a =79		local b = 3;80		181	"#828384	no_rhs => r#"85		a +86	"#87	no_lhs => r#"88		+ 289	"#90	no_operator => "91		2 292	"9394	named_before_positional => "95		a(1, 2, b=4, 3, 5, k = 12, 6)96	"9798	wrong_field_end => "99		{100			a: 1;101			b: 2;102		}103	"104105106	plain_call => "107		std.substr(a, 0, std.length(b)) == b108	"109110	destruct => "111		local [a, b, c] = arr;112		local [a, ...] = arr_rest;113		local [..., a] = rest_arr;114		local [...] = rest_in_arr;115		local [a, ...n] = arr_rest_n;116		local [...n, a] = rest_arr_n;117		local [...n] = rest_in_arr_n;118119		local {a, b, c} = obj;120		local {a, b, c, ...} = obj_rest;121		local {a, b, c, ...n} = obj_rest_n;122123		null124	"125126	str_block_missing_indent => "127		|||128	"129	str_block_missing_termination => "130		|||131			hello132	"133	str_block_missing_newline => "134		|||hello135	"136	str_block_missing_indent_text => "137		|||138		hello139	"140141	unexpected_destruct => "142		local * = 1;143		a144	"145	arr_compspec => r#"146		[a for a in [1, 2, 3]]147	"#148	arr_compspec_comma => "149		[a, for a in [1, 2, 3]]150	"151	arr_compspec_no_elems => "152		[for a in [1, 2, 3]]153	"154	arr_compspec_incompatible_with_multiple_elems => r#"155		[a for a in [1, 2, 3], b]156	"#157	arr_compspec_incompatible_with_multiple_elems_w => r#"158		[a, b, for a in [1, 2, 3], c]159	"#160161	obj_compspec => r#"162		{a:1 for a in [1, 2, 3]}163	"#164	obj_compspec_comma => "165		{a:1, for a in [1, 2, 3]}166	"167	obj_compspec_no_elems => "168		{for a in [1, 2, 3]}169	"170	obj_compspec_incompatible_with_multiple_elems => r#"171		{a:1 for a in [1, 2, 3], b:1}172	"#173	obj_compspec_incompatible_with_multiple_elems_w => r#"174		{a:1, b:1, for a in [1, 2, 3], c:1}175	"#176177	obj_compspec_incompatible_with_asserts => r#"178		{assert 1, a: 1 for a in [1,2,3]}179	"#180181	local_method => r#"182		local183			a(x) = x,184			a = function(x) x,185		; c186	"#187	obj_method => r#"188		{189			a(x): x,190			a: function(x) x,191		}192	"#193194	continue_after_total_failure => r#"195		local intr = $intrinsic(test);196197		local a = 1, b = 2, c = a + b;198199		[c]200	"#201202	super_nesting => r#"203		super.a + super.b204	"#205206	string_block_trim => r#"207		|||-208			Trimmed text block209		|||210	"#211212	visibilities => r#"213		{214			normal: 1,215			hide:: 2,216			unhide::: 3,217		}218	"#219220	unary_not => r#"221		!false222	"#223224	unary_not_in_call => r#"225		std.assertEqual(!false, true)226	"#227228	local_in_binop_rhs => r#"229		a + local x = 1; x230	"#231232	for_obj_spec_visible => r#"233		{ [k]: v for [k]: v in obj }234	"#235	for_obj_spec_hidden => r#"236		{ [k]: v for [k]:: v in obj }237	"#238	for_obj_spec_force_visible => r#"239		{ [k]: v for [k]::: v in obj }240	"#241	for_obj_spec_value_destruct => r#"242		{ [k]: a + b for [k]: [a, b] in obj }243	"#244245	multi_line_comment_doc => r#"246		{ a:: 1, /** doc **/ b:: 2 }247	"#248	multi_line_comment_empty => r#"249		/**/ 1250	"#251	multi_line_comment_triple_star => r#"252		/***/ 2253	"#254	multi_line_comment_inner_star => r#"255		/* * */ 3256	"#257	multi_line_comment_too_short => r#"258		/*/259	"#260	multi_line_comment_unterminated => r#"261		/** unterminated262	"#263);264265#[test]266fn eval_simple() {267	let src = "local a = 1, b = 2; a + local c = 1; c";268	let (node, _errors) = parse(src);269270	dbg!(node);271}