Unified: Support string interpolation - #22549
Conversation
| final F::Expr getAnElement() { result = this.getElement(_) } | ||
|
|
||
| /** Gets the node corresponding to the field `modifier`. */ | ||
| final F::Modifier getModifier(int i) { |
There was a problem hiding this comment.
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
StringInterpolationExprand 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.
tausbn
left a comment
There was a problem hiding this comment.
Looks good to me, apart from one minor comment (that can be addressed when we eventually "dequote" string literals in the extractor).
| 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 | ||
| ) |
There was a problem hiding this comment.
What if the constant segment represents a string beginning and ending with quotes?
There was a problem hiding this comment.
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.
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:To map this into a more traditional AST structure, we wrap each interpolation in a
CallExprtargeting a built-in calledinterpolation. We'll add value-steps through simpleinterpolationcalls (those with exactly one, unnamed, argument).In the future we can resolve these calls to actual
appendInterpolationimplementations and add flow from the receiver's post-update node to the out-node, which will make data flow work in practice.