Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-10241] A way to get raw string without quotes from StringLiteralExprSyntax #433

Closed
swift-ci opened this issue Mar 30, 2019 · 8 comments
Closed

Comments

@swift-ci
Copy link
Contributor

@swift-ci swift-ci commented Mar 30, 2019

Previous ID SR-10241
Radar None
Original Reporter kitasuke (JIRA User)
Type Improvement
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s SwiftSyntax
Labels Improvement
Assignee kitasuke (JIRA)
Priority Medium

md5: 0345f8455f9bcaa284679f0dc943b32a

relates to:

  • SR-10469 Unknown syntax for interpolated string literal

Issue Description:

Background
I would like to have a better way to extract raw string without quotes from `StringLiteralExprSyntax`. `StringInterpolationExprSyntax` looks well-organized because its cursor has openQuote, segments and closeQuote to express strings and quotes separately.

My proposal

Can we have quotes in children of StringLiteralExpr like StringInterpolationExpr?
https://github.com/apple/swift/blob/c04a7dec9f739fbe53f3c305a32e8d426972bfd8/utils/gyb_syntax_support/ExprNodes.py#L266:L269

https://github.com/apple/swift/blob/c04a7dec9f739fbe53f3c305a32e8d426972bfd8/utils/gyb_syntax_support/ExprNodes.py#L468:L481

References

Data structures and examples are below.

public struct StringLiteralExprSyntax: ExprSyntax, _SyntaxBase, Hashable {
  enum Cursor: Int {
    case stringLiteral
  }
}
// let foo = "foo"
print(node.stringLiteral.text) // "\"foo\""
public struct StringInterpolationExprSyntax: ExprSyntax, _SyntaxBase, Hashable {
  enum Cursor: Int {
    case openQuote
    case segments
    case closeQuote
  }
}
// let foo = "foo \(bar)"
print((node.segments[0] as! StringSegmentSyntax).content.text) // "foo"
@rintaro
Copy link
Mannequin

@rintaro rintaro mannequin commented Apr 2, 2019

@akyrtzi
Copy link
Member

@akyrtzi akyrtzi commented Apr 3, 2019

Seems good idea to me. The benefit is you will be able to structurally distinguish what kind of quotes (multiline or single) were used, instead of searching the string literal text string in order to distinguish.

If we do this we should probably get rid of 'string_literal' token kind and use 'string_segment' token kind for the non-interpolation case as well.

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Apr 3, 2019

Comment by Yusuke Kita (JIRA)

Exactly.

Can I implement this fix? Seems quite interesting to dive into more details.

@akyrtzi
Copy link
Member

@akyrtzi akyrtzi commented Apr 3, 2019

Sure! Note that after changing the syntax definition file it would need a change on the C++ parser side.

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Apr 12, 2019

Comment by Yusuke Kita (JIRA)

I have a question about literal expression for this. I'm looking into Parser and wondering whether I should extend 'StringLiteralExpr' or create new one like 'NonInterpolatedStringLiteralExpr'. Which one do you think is better? @akyrtzi

I figured out how 'string_segment' is parsed in 'parseExprStringLiteral' func, but I haven't had conclusion for the interface yet.

@rintaro
Copy link
Mannequin

@rintaro rintaro mannequin commented Apr 12, 2019

I think we should generalize StringLiteralExpr.
Basically, syntax change would be:

  • Remove StringLiteralExpr

  • Rename StringInterpolationExpr to StringLiteralExpr

  • Rename StringInterpolationSegments to StringLiteralSegment

like:

    Node('StringLiteralExpr', kind='Expr',
         children=[
             Child('OpenQuote', kind='Token',
                   token_choices=[
                       'StringQuoteToken',
                       'MultilineStringQuoteToken',
                   ]),
             Child('Segments', kind='StringLiteralSegments'),
             Child('CloseQuote', kind='Token',
                   token_choices=[
                       'StringQuoteToken',
                       'MultilineStringQuoteToken',
                   ]),
         ]),

We can easily check whether it's interpolated or not by (segments.count == 1 && segments[0] is StringSegmentToken)

@nkcsgexi
Copy link
Member

@nkcsgexi nkcsgexi commented Apr 12, 2019

I'm not a big fan of adding `NonInterpolatedStringLiteralExpr` either. The reason is users are likely to have two overrides for either visit or rewrite functions to handle all string literal cases. We should strive to help users reduce code duplication. However, feel free to add a convenient function to `StringLIteralExpr` indicating whether there are interpolations in the node.

@swift-ci
Copy link
Contributor Author

@swift-ci swift-ci commented Apr 13, 2019

Comment by Yusuke Kita (JIRA)

What Rintaro suggested makes sense to me. I'll go with `StringLiteralExpr` for the case. Thanks for your feedbacks!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 9, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants