git.delta.rocks / jrsonnet / refs/commits / 0f5424fc1b4b

difftreelog

feat(rowan) alternative object comp syntax

lmvywrutYaroslav Bolyukin2026-05-06parent: #604f09d.patch.diff
in: master

10 files changed

modifiedcrates/jrsonnet-formatter/src/lib.rsdiffbeforeafterboth
13 AstNode, AstToken as _, SyntaxToken,13 AstNode, AstToken as _, SyntaxToken,
14 nodes::{14 nodes::{
15 Arg, ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,15 Arg, ArgsDesc, Assertion, BinaryOperator, Bind, CompSpec, Destruct, DestructArrayPart,
16 DestructRest, Expr, ExprArray, ExprBase, FieldName, ForSpec, IfSpec, ImportKind, Literal,16 DestructRest, Expr, ExprArray, ExprBase, FieldName, ForObjSpec, ForSpec, IfSpec,
17 Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc, SourceFile, Stmt, Suffix,17 ImportKind, Literal, Member, Name, Number, ObjBody, ObjLocal, ParamsDesc, SliceDesc,
18 Text, TextKind, UnaryOperator, Visibility,18 SourceFile, Stmt, Suffix, Text, TextKind, UnaryOperator, Visibility,
19 },19 },
645 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()});645 p!(out, str("for ") {self.bind()} str(" in ") {self.expr()});
646 }646 }
647}647}
648impl Printable for ForObjSpec {
649 fn print(&self, out: &mut PrintItems) {
650 p!(out, str("for [") {self.key()} str("]") {self.visibility()} str(" ") {self.value()} str(" in ") {self.expr()});
651 }
652}
648impl Printable for IfSpec {653impl Printable for IfSpec {
649 fn print(&self, out: &mut PrintItems) {654 fn print(&self, out: &mut PrintItems) {
650 p!(out, str("if ") {self.expr()});655 p!(out, str("if ") {self.expr()});
654 fn print(&self, out: &mut PrintItems) {659 fn print(&self, out: &mut PrintItems) {
655 match self {660 match self {
656 Self::ForSpec(f) => f.print(out),661 Self::ForSpec(f) => f.print(out),
662 Self::ForObjSpec(f) => f.print(out),
657 Self::IfSpec(i) => i.print(out),663 Self::IfSpec(i) => i.print(out),
658 }664 }
659 }665 }
modifiedcrates/jrsonnet-rowan-parser/jsonnet.ungramdiffbeforeafterboth
246 bind:Destruct246 bind:Destruct
247 'in'247 'in'
248 Expr248 Expr
249ForObjSpec =
250 'for'
251 '['
252 key:Name
253 ']'
254 Visibility
255 value:Destruct
256 'in'
257 Expr
249IfSpec =258IfSpec =
250 'if'259 'if'
251 Expr260 Expr
252CompSpec =261CompSpec =
253 ForSpec262 ForSpec
263| ForObjSpec
254| IfSpec264| IfSpec
255265
256BindDestruct =266BindDestruct =
modifiedcrates/jrsonnet-rowan-parser/src/generated/nodes.rsdiffbeforeafterboth
649 }649 }
650}650}
651
652#[derive(Debug, Clone, PartialEq, Eq, Hash)]
653pub struct ForObjSpec {
654 pub(crate) syntax: SyntaxNode,
655}
656impl ForObjSpec {
657 pub fn for_kw_token(&self) -> Option<SyntaxToken> {
658 support::token(&self.syntax, T![for])
659 }
660 pub fn l_brack_token(&self) -> Option<SyntaxToken> {
661 support::token(&self.syntax, T!['['])
662 }
663 pub fn key(&self) -> Option<Name> {
664 support::children(&self.syntax).next()
665 }
666 pub fn r_brack_token(&self) -> Option<SyntaxToken> {
667 support::token(&self.syntax, T![']'])
668 }
669 pub fn visibility(&self) -> Option<Visibility> {
670 support::children(&self.syntax).next()
671 }
672 pub fn value(&self) -> Option<Destruct> {
673 support::children(&self.syntax).next()
674 }
675 pub fn in_kw_token(&self) -> Option<SyntaxToken> {
676 support::token(&self.syntax, T![in])
677 }
678 pub fn expr(&self) -> Option<Expr> {
679 support::children(&self.syntax).next()
680 }
681}
651682
652#[derive(Debug, Clone, PartialEq, Eq, Hash)]683#[derive(Debug, Clone, PartialEq, Eq, Hash)]
653pub struct IfSpec {684pub struct IfSpec {
845#[derive(Debug, Clone, PartialEq, Eq, Hash)]876#[derive(Debug, Clone, PartialEq, Eq, Hash)]
846pub enum CompSpec {877pub enum CompSpec {
847 ForSpec(ForSpec),878 ForSpec(ForSpec),
879 ForObjSpec(ForObjSpec),
848 IfSpec(IfSpec),880 IfSpec(IfSpec),
849}881}
850882
1702 &self.syntax1734 &self.syntax
1703 }1735 }
1704}1736}
1737impl AstNode for ForObjSpec {
1738 fn can_cast(kind: SyntaxKind) -> bool {
1739 kind == FOR_OBJ_SPEC
1740 }
1741 fn cast(syntax: SyntaxNode) -> Option<Self> {
1742 if Self::can_cast(syntax.kind()) {
1743 Some(Self { syntax })
1744 } else {
1745 None
1746 }
1747 }
1748 fn syntax(&self) -> &SyntaxNode {
1749 &self.syntax
1750 }
1751}
1705impl AstNode for IfSpec {1752impl AstNode for IfSpec {
1706 fn can_cast(kind: SyntaxKind) -> bool {1753 fn can_cast(kind: SyntaxKind) -> bool {
1707 kind == IF_SPEC1754 kind == IF_SPEC
2014 CompSpec::ForSpec(node)2061 CompSpec::ForSpec(node)
2015 }2062 }
2016}2063}
2064impl From<ForObjSpec> for CompSpec {
2065 fn from(node: ForObjSpec) -> CompSpec {
2066 CompSpec::ForObjSpec(node)
2067 }
2068}
2017impl From<IfSpec> for CompSpec {2069impl From<IfSpec> for CompSpec {
2018 fn from(node: IfSpec) -> CompSpec {2070 fn from(node: IfSpec) -> CompSpec {
2019 CompSpec::IfSpec(node)2071 CompSpec::IfSpec(node)
2022impl AstNode for CompSpec {2074impl AstNode for CompSpec {
2023 fn can_cast(kind: SyntaxKind) -> bool {2075 fn can_cast(kind: SyntaxKind) -> bool {
2024 match kind {2076 match kind {
2025 FOR_SPEC | IF_SPEC => true,2077 FOR_SPEC | FOR_OBJ_SPEC | IF_SPEC => true,
2026 _ => false,2078 _ => false,
2027 }2079 }
2028 }2080 }
2029 fn cast(syntax: SyntaxNode) -> Option<Self> {2081 fn cast(syntax: SyntaxNode) -> Option<Self> {
2030 let res = match syntax.kind() {2082 let res = match syntax.kind() {
2031 FOR_SPEC => CompSpec::ForSpec(ForSpec { syntax }),2083 FOR_SPEC => CompSpec::ForSpec(ForSpec { syntax }),
2084 FOR_OBJ_SPEC => CompSpec::ForObjSpec(ForObjSpec { syntax }),
2032 IF_SPEC => CompSpec::IfSpec(IfSpec { syntax }),2085 IF_SPEC => CompSpec::IfSpec(IfSpec { syntax }),
2033 _ => return None,2086 _ => return None,
2034 };2087 };
2037 fn syntax(&self) -> &SyntaxNode {2090 fn syntax(&self) -> &SyntaxNode {
2038 match self {2091 match self {
2039 CompSpec::ForSpec(it) => &it.syntax,2092 CompSpec::ForSpec(it) => &it.syntax,
2093 CompSpec::ForObjSpec(it) => &it.syntax,
2040 CompSpec::IfSpec(it) => &it.syntax,2094 CompSpec::IfSpec(it) => &it.syntax,
2041 }2095 }
2042 }2096 }
3016 std::fmt::Display::fmt(self.syntax(), f)3070 std::fmt::Display::fmt(self.syntax(), f)
3017 }3071 }
3018}3072}
3073impl std::fmt::Display for ForObjSpec {
3074 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3075 std::fmt::Display::fmt(self.syntax(), f)
3076 }
3077}
3019impl std::fmt::Display for IfSpec {3078impl std::fmt::Display for IfSpec {
3020 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {3079 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3021 std::fmt::Display::fmt(self.syntax(), f)3080 std::fmt::Display::fmt(self.syntax(), f)
modifiedcrates/jrsonnet-rowan-parser/src/generated/syntax_kinds.rsdiffbeforeafterboth
145 FIELD_NAME_FIXED,145 FIELD_NAME_FIXED,
146 FIELD_NAME_DYNAMIC,146 FIELD_NAME_DYNAMIC,
147 FOR_SPEC,147 FOR_SPEC,
148 FOR_OBJ_SPEC,
148 IF_SPEC,149 IF_SPEC,
149 BIND_DESTRUCT,150 BIND_DESTRUCT,
150 BIND_FUNCTION,151 BIND_FUNCTION,
modifiedcrates/jrsonnet-rowan-parser/src/parser.rsdiffbeforeafterboth
364fn compspec(p: &mut Parser) -> CompletedMarker {364fn compspec(p: &mut Parser) -> CompletedMarker {
365 assert!(p.at_ts(COMPSPEC));365 assert!(p.at_ts(COMPSPEC));
366 if p.at(T![for]) {366 if p.at(T![for]) {
367 if p.nth_at(1, T!['[']) && p.nth_at(2, IDENT) && p.nth_at(3, T![']']) && p.nth_at(4, T![:])
368 {
369 let m = p.start();
370 p.bump_assert(T![for]);
371 p.bump_assert(T!['[']);
372 name(p);
373 p.expect(T![']']);
374 visibility(p);
375 destruct(p);
376 p.expect(T![in]);
377 expr(p);
378 return m.complete(p, FOR_OBJ_SPEC);
379 }
367 let m = p.start();380 let m = p.start();
368 p.bump();381 p.bump();
369 destruct(p);382 destruct(p);
addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__for_obj_spec_force_visible.snapdiffbeforeafterboth

no changes

addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__for_obj_spec_hidden.snapdiffbeforeafterboth

no changes

addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__for_obj_spec_value_destruct.snapdiffbeforeafterboth

no changes

addedcrates/jrsonnet-rowan-parser/src/snapshots/jrsonnet_rowan_parser__tests__for_obj_spec_visible.snapdiffbeforeafterboth

no changes

modifiedcrates/jrsonnet-rowan-parser/src/tests.rsdiffbeforeafterboth
229 a + local x = 1; x229 a + local x = 1; x
230 "#230 "#
231
232 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 "#
231);244);
232245
233#[test]246#[test]