Skip to content

Commit a61d1f6

Browse files
author
Harlan Haskins
committed
[ParseableInterfaces] Re-escape multi-line strings in attribute messages
Previously, we would print multi-line string literals with single quotes, which were not re-parseable. Instead, re-escape their contents and print them out escaped.
1 parent e9d81e1 commit a61d1f6

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ class ASTPrinter {
207207
return *this;
208208
}
209209

210+
void printEscapedStringLiteral(StringRef str);
211+
210212
void printName(Identifier Name,
211213
PrintNameContext Context = PrintNameContext::Normal);
212214

lib/AST/ASTPrinter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,22 @@ void ASTPrinter::printTextImpl(StringRef Text) {
270270
printText(Text);
271271
}
272272

273+
void ASTPrinter::printEscapedStringLiteral(StringRef str) {
274+
SmallString<128> encodeBuf;
275+
StringRef escaped =
276+
Lexer::getEncodedStringSegment(str, encodeBuf,
277+
/*isFirstSegment*/true,
278+
/*isLastSegment*/true,
279+
/*indentToStrip*/~0U /* sentinel */);
280+
281+
// FIXME: This is wasteful, but ASTPrinter is an abstract class that doesn't
282+
// have a directly-accessible ostream.
283+
SmallString<128> escapeBuf;
284+
llvm::raw_svector_ostream os(escapeBuf);
285+
os << QuotedString(escaped);
286+
printTextImpl(escapeBuf.str());
287+
}
288+
273289
void ASTPrinter::printTypeRef(Type T, const TypeDecl *RefTo, Identifier Name) {
274290
PrintNameContext Context = PrintNameContext::Normal;
275291
if (isa<GenericTypeParamDecl>(RefTo)) {

lib/AST/Attr.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,10 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
460460
// If there's no message, but this is specifically an imported
461461
// "unavailable in Swift" attribute, synthesize a message to look good in
462462
// the generated interface.
463-
if (!Attr->Message.empty())
464-
Printer << ", message: \"" << Attr->Message << "\"";
463+
if (!Attr->Message.empty()) {
464+
Printer << ", message: ";
465+
Printer.printEscapedStringLiteral(Attr->Message);
466+
}
465467
else if (Attr->getPlatformAgnosticAvailability()
466468
== PlatformAgnosticAvailabilityKind::UnavailableInSwift)
467469
Printer << ", message: \"Not available in Swift\"";

0 commit comments

Comments
 (0)