Skip to content

fix(swift): scan expression identifiers by UAX 31 XID_Continue - #3547

Open
karolkulesza wants to merge 12 commits into
a2ui-project:mainfrom
karolkulesza:fix/swift-expression-xid-identifiers
Open

karolkulesza wants to merge 12 commits into
a2ui-project:mainfrom
karolkulesza:fix/swift-expression-xid-identifiers

Conversation

@karolkulesza

@karolkulesza karolkulesza commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Description

The Swift expression parser used Character.isLetter || isNumber to scan paths, function names, argument names and the character after true / false / null. isNumber also accepts characters such as ½ and ², so Swift parsed ${a½} as a path and ${add(½: 1)} as a call. web_core, Dart and Python scan by UAX 31 XID_Continue and reject both.

This PR makes Swift scan by XID_Continue too: a Character counts when all of its scalars are XID_Continue. Paths still allow /, . and -, and are also checked per scalar, because a Swift Character is a grapheme cluster and a separator followed by a combining mark such as U+0301 arrives as one Character. Like the other parsers, it does not require XID_Start for the first character.

It also adds eight shared cases to conformance/core/expressions.yaml: non-ASCII path, function and argument names, a keyword followed by ß, combining marks (including right after / and .) and the supplementary-plane 𠮷 are accepted, and ½ in a path, after a keyword and in an argument name, and 🚀 in a path are rejected.

Testing:

  • Swift: swift test passes (685 tests; the only issues are the 4 existing known issues in AdapterConformanceTests). Without the parser change, the three ½ cases and the combining-mark path case fail.
  • web_core (expression_parser.conformance.test.js), Dart (expressions_conformance_test.dart) and Python (test_conformance.py) pass the new cases without changes.
  • swift-format lint --strict is clean.

Part of #2838

Pre-launch Checklist

One time:

For this PR:

  • I have updated the relevant CHANGELOG.md file. (There is no Swift CHANGELOG.)
  • I updated/added relevant documentation. (No documentation change needed.)
  • My code changes (if any) have tests.
  • If my branch is on a fork, I have verified that scripts/e2e_test.sh passes.

If you need help, consider asking for advice on the discussion board.

The Swift expression parser decided which characters belong to a path,
function name, argument name or keyword with Character.isLetter and
isNumber. isNumber also accepts characters such as ½ and ², so Swift
parsed ${a½} as a path and ${add(½: 1)} as a call, while web_core, Dart
and Python reject both.

Scan by UAX 31 XID_Continue instead, like the other engines: a
character counts when all of its scalars are XID_Continue. Paths still
allow /, . and -.

Add shared cases to conformance/core/expressions.yaml for non-ASCII
paths, function names, argument names and keyword boundaries, and for
rejecting ½. They pass in the Swift, web_core, Dart and Python runners.

Part of a2ui-project#2838

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Swift expression parser to support non-ASCII characters in paths, identifiers, and function/argument names using the UAX #31 XID_Continue standard, and adds corresponding conformance tests. Feedback on the changes suggests optimizing the isIdentifierCharacter method with a fast-path check for ASCII characters to prevent potential performance overhead from Unicode scalar property lookups.

@github-actions github-actions Bot added the status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs label Oct 23, 2026
@gspencergoog
gspencergoog requested a review from pinieb October 29, 2026 20:48
@pinieb pinieb added the lang: swift Affects SDKs or apps in the Swift programming language label Oct 29, 2026
Comment thread conformance/core/expressions.yaml Resolved
@github-actions github-actions Bot removed the status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs label Oct 29, 2026
…ombining marks

A Swift Character is a grapheme cluster, so a '/', '.' or '-' followed by a
combining mark such as U+0301 arrives as one Character and was rejected,
while web_core, Dart and Python accept it. Check path characters scalar by
scalar, fold the scan predicates into the while-let conditions, and
flatten matchesKeyword with a guard.

Add shared conformance cases for combining marks (including right after a
slash or dot), a supplementary-plane XID_Continue character, and a
supplementary-plane character outside XID_Continue.
@github-actions github-actions Bot added status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs and removed status: waiting-for-author-response labels Oct 30, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lang: swift Affects SDKs or apps in the Swift programming language status: needs-triage auto-managed: https://github.com/a2ui-project/a2ui/blob/main/scripts/triage.mjs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants