Skip to content

Unified: Support string interpolation - #22549

Merged
asgerf merged 6 commits into
github:mainfrom
asgerf:unified/string-interpolation
Sep 11, 2026
Merged

Unified: Support string interpolation#22549
asgerf merged 6 commits into
github:mainfrom
asgerf:unified/string-interpolation

Conversation

@asgerf

@asgerf asgerf commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Adds support for string interpolation by adding a new AST node, StringInterpolationExpr, and corresponding mappings.

In Swift, the syntax for string interpolation is \(...), e.g. "foo \(bar) baz".

However, the stuff between \(...) can be an arbitrary argument list, as it is internally call to appendInterpolation. For example this is valid syntax:

"foo \(1, 2, 3) bar"
"foo \(named: x) bar"

To map this into a more traditional AST structure, we wrap each interpolation in a CallExpr targeting a built-in called interpolation. We'll add value-steps through simple interpolation calls (those with exactly one, unnamed, argument).

In the future we can resolve these calls to actual appendInterpolation implementations and add flow from the receiver's post-update node to the out-node, which will make data flow work in practice.

@asgerf asgerf added the no-change-note-required This PR does not need a change note label Sep 11, 2026
@asgerf
asgerf requested a balanced review from Copilot September 11, 2026 09:12
final F::Expr getAnElement() { result = this.getElement(_) }

/** Gets the node corresponding to the field `modifier`. */
final F::Modifier getModifier(int i) {

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Interpolated string segments are emitted in a format that prevents Expr.getStringValue() from recovering their values.

Review tier: Lite
Findings: None

What changed in this PR

Adds Unified AST support for Swift string interpolation.

Changes:

  • Introduces StringInterpolationExpr and schema/QL bindings.
  • Maps interpolation segments and arguments into AST nodes.
  • Adds Swift corpus coverage.
File Summary
unified/​ql/​lib/​unified.dbscheme Adds interpolation schema relations.
unified/​ql/​lib/​codeql/​unified/​internal/​Ast.qll Exposes interpolation AST APIs.
unified/​extractor/​tests/​corpus/​swift/​literals/​string-with-interpolation.swift Adds interpolation inputs.
unified/​extractor/​tests/​corpus/​swift/​literals/​string-with-interpolation.output Records expected output.
unified/​extractor/​src/​languages/​swift/​swift.rs Implements Swift interpolation mappings.
unified/​extractor/​ast_types.yml Defines the interpolation AST node.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@asgerf
asgerf marked this pull request as ready for review September 11, 2026 11:25
@asgerf
asgerf requested review from a team as code owners September 11, 2026 11:25

@tausbn tausbn 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.

Looks good to me, apart from one minor comment (that can be addressed when we eventually "dequote" string literals in the extractor).

Comment on lines +56 to +62
exists(string text | text = this.(StringLiteral).getValue() |
result = text.regexpCapture("\"(.*)\"", 1)
or
// Constant-segments of string interpolations are represented as string literals, but their raw text does not have quotes
not exists(text.regexpCapture("\"(.*)\"", 1)) and
result = text
)

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.

What if the constant segment represents a string beginning and ending with quotes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For common double-quoted strings it should not be possible to start with " because it needs to be escaped, as in \", and the raw text would include the backslash. Single-quoted strings are not possible in Swift.

For more exotic string literals it can fail, but I'm happy not to support those right now. That should come after moving the string-cooking into the extractor.

@asgerf
asgerf merged commit 9ddc15c into github:main Sep 11, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants