outfoxx/swiftpoet

Formatting string produces error

Closed this issue · 14 comments

We are using SwiftPoet on the Wire project to emit Swift code from proto files.

The test harness includes a proto file with a bunch of default values like this string:
https://github.com/square/wire/blob/master/wire-tests/src/commonTest/proto/kotlin/all_types.proto#L118

We read the value from the proto as a String and emit code:

CodeBlock.of("%S", defaultValue)

However the output code contains invalid characters and compilation fails. You can see the output here https://github.com/square/wire/pull/2514/files#diff-1b5612904d5c974962f1768754be37a013906a6ce05417992c9cbd14e97b81d4R255-R258

The error:

/Users/dnkoutso/Development/wire/wire-tests-swift/src/main/swift/AllTypes.swift:257:14: error: unprintable ASCII character found in source file
        
        ~güzel

KotlinPoet outputs https://github.com/square/wire/blob/master/wire-tests/src/commonTest/proto-kotlin/com/squareup/wire/protos/kotlin/alltypes/AllTypes.kt#L1991-L1992 which seems to be working.

kdubb commented

Obviously somebody should be double escaping this string I'm just now sure who. At first thought just blindly double escaping every "%S" seems wrong? But I could be be wrong.

Do you know how KotlinPoet achieves this?

kdubb commented

One thing to remember as well is that Swift string literals allow for a fairly wide range of input (e.g. multiple code-point emojis).

hmmm seems like SwiftPoet also does this...

Hm this is weird not seeing KotlinGenerator in Wire doing anything different than just delegating to KotlinPoet https://github.com/square/wire/blob/master/wire-kotlin-generator/src/main/java/com/squareup/wire/kotlin/KotlinGenerator.kt#L1394

kdubb commented

Yes. Much of the CodeWriter was literally yanked from KotlinPoet as I originally sent an offer to Jake to donate this and have it hosted with the other poets and all share a community.

I guess the only difference I see is isConstantContext ? I think its defaulting to false in KotlinPoet and prints the string differently rather than a multi-line string.

kdubb commented

It looks like there's been quite a few updates to these classes since the departure.

yeah...I am trying to test a quick case if this is the issue

@kdubb I managed to just copy paste some parts to test it out quickly and indeed it seems to be the issue. It seems we fall under a different code path as we treat this as a multi-line string.

Looks like updating this logic to catch up to what KotlinPoet does would fix this issue.

kdubb commented

Can you provide a PR?

kdubb commented

Thanks for the investigation!

I will give it a shot! :D

kdubb commented

One other thing is I've looked at this code a few times in the past because I don't think it aligns with Swift's string rules. It may be that we end up with a bit different scheme to ensure it handles Swift strings correctly.