mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[libSyntax] Add a reference counted version of OwnedString
We cannot use unowned strings for token texts of incrementally parsed syntax trees since the source buffer to which reused nodes refer will have been freed for reused nodes. Always copying the token text whenever OwnedString is passed is too expensive. A reference counted copy of the string allows us to keep the token's string alive across incremental parses while eliminating unnecessary copies.
This commit is contained in:
@@ -404,12 +404,17 @@ public:
|
||||
return static_cast<tok>(Bits.Token.TokenKind);
|
||||
}
|
||||
|
||||
/// Return the text of the token.
|
||||
StringRef getTokenText() const {
|
||||
/// Return the text of the token as an \c OwnedString. Keeping a reference to
|
||||
/// this string will keep it alive even if the syntax node gets freed.
|
||||
OwnedString getOwnedTokenText() const {
|
||||
assert(isToken());
|
||||
return getTrailingObjects<OwnedString>()->str();
|
||||
return *getTrailingObjects<OwnedString>();
|
||||
}
|
||||
|
||||
/// Return the text of the token as a reference. The referenced buffer may
|
||||
/// disappear when the syntax node gets freed.
|
||||
StringRef getTokenText() const { return getOwnedTokenText().str(); }
|
||||
|
||||
/// Return the leading trivia list of the token.
|
||||
ArrayRef<TriviaPiece> getLeadingTrivia() const {
|
||||
assert(isToken());
|
||||
@@ -434,7 +439,7 @@ public:
|
||||
/// trivia instead.
|
||||
RC<RawSyntax>
|
||||
withLeadingTrivia(ArrayRef<TriviaPiece> NewLeadingTrivia) const {
|
||||
return make(getTokenKind(), getTokenText(), NewLeadingTrivia,
|
||||
return make(getTokenKind(), getOwnedTokenText(), NewLeadingTrivia,
|
||||
getTrailingTrivia(), getPresence());
|
||||
}
|
||||
|
||||
@@ -446,7 +451,7 @@ public:
|
||||
/// trivia instead.
|
||||
RC<RawSyntax>
|
||||
withTrailingTrivia(ArrayRef<TriviaPiece> NewTrailingTrivia) const {
|
||||
return make(getTokenKind(), getTokenText(), getLeadingTrivia(),
|
||||
return make(getTokenKind(), getOwnedTokenText(), getLeadingTrivia(),
|
||||
NewTrailingTrivia, getPresence());
|
||||
}
|
||||
|
||||
|
||||
@@ -162,9 +162,9 @@ template <> struct MappingTraits<swift::RC<swift::RawSyntax>> {
|
||||
StringRef nodeIdString;
|
||||
in.mapRequired("id", nodeIdString);
|
||||
unsigned nodeId = std::atoi(nodeIdString.data());
|
||||
value =
|
||||
swift::RawSyntax::make(tokenKind, text, leadingTrivia, trailingTrivia,
|
||||
presence, /*Arena=*/nullptr, nodeId);
|
||||
value = swift::RawSyntax::make(
|
||||
tokenKind, swift::OwnedString::makeRefCounted(text), leadingTrivia,
|
||||
trailingTrivia, presence, /*Arena=*/nullptr, nodeId);
|
||||
} else {
|
||||
swift::SyntaxKind kind;
|
||||
in.mapRequired("kind", kind);
|
||||
|
||||
@@ -454,7 +454,8 @@ struct MappingTraits<swift::syntax::TriviaPiece> {
|
||||
% else:
|
||||
StringRef text;
|
||||
in.mapRequired("value", text);
|
||||
return swift::syntax::TriviaPiece(kind, text);
|
||||
return swift::syntax::TriviaPiece(
|
||||
kind, swift::OwnedString::makeRefCounted(text));
|
||||
% end
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user