Skip to content

Commit b863d5b

Browse files
Andries-Smitclaude
andcommitted
fix(lint): handle chained XPath predicates in stripXPathBrackets
[a = 1][b = 2] was incorrectly stripped to a = 1][b = 2 because the check only looked at the first and last characters. The fix walks bracket depth to confirm the opening [ at position 0 is matched by the final ] before stripping. Added two test cases for chained predicates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R1yYeYn9rosf8UdAimdatt
1 parent a7f55be commit b863d5b

2 files changed

Lines changed: 24 additions & 2 deletions

File tree

mdl/linter/starlark_xpath.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,29 @@ import (
1313

1414
// stripXPathBrackets removes the outer [ and ] from a Mendix XPath constraint string.
1515
// Returns the inner expression ready for parsing.
16+
// Only strips when the opening [ at position 0 is matched by the final ] (i.e. they
17+
// form a single outer pair). Chained predicates like [a = 1][b = 2] are returned as-is.
1618
func stripXPathBrackets(s string) string {
1719
s = strings.TrimSpace(s)
18-
if strings.HasPrefix(s, "[") && strings.HasSuffix(s, "]") {
19-
return s[1 : len(s)-1]
20+
if !strings.HasPrefix(s, "[") || !strings.HasSuffix(s, "]") {
21+
return s
22+
}
23+
// Walk forward to find where the first '[' closes.
24+
depth := 0
25+
for i, ch := range s {
26+
switch ch {
27+
case '[':
28+
depth++
29+
case ']':
30+
depth--
31+
if depth == 0 {
32+
if i == len(s)-1 {
33+
return s[1 : len(s)-1]
34+
}
35+
// First '[' closes before the end — chained predicates; don't strip.
36+
return s
37+
}
38+
}
2039
}
2140
return s
2241
}

mdl/linter/starlark_xpath_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ func TestStripXPathBrackets(t *testing.T) {
9393
{"Status = 'Active'", "Status = 'Active'"},
9494
{" [foo] ", "foo"},
9595
{"", ""},
96+
// Chained predicates must not be partially stripped.
97+
{"[a = 1][b = 2]", "[a = 1][b = 2]"},
98+
{"[a = 1][b = 2][c = 3]", "[a = 1][b = 2][c = 3]"},
9699
}
97100
for _, c := range cases {
98101
got := stripXPathBrackets(c.in)

0 commit comments

Comments
 (0)