Skip to content

[ASTGen] Move logic in BridgedASTContext.getIdentifier() to ASTGen #70220

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

Merged
merged 3 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ inline const void *_Nullable BridgedIdentifier_raw(BridgedIdentifier ident) {
return ident.Raw;
}

struct BridgedIdentifierAndSourceLoc {
struct BridgedLocatedIdentifier {
SWIFT_NAME("name")
BridgedIdentifier Name;

Expand Down
22 changes: 5 additions & 17 deletions lib/AST/ASTBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,7 @@ BridgedDeclNameLoc_createParsed(BridgedSourceLoc cBaseNameLoc) {

BridgedIdentifier BridgedASTContext_getIdentifier(BridgedASTContext cContext,
BridgedStringRef cStr) {
StringRef str = cStr.unbridged();
if (str.size() == 1 && str.front() == '_')
return BridgedIdentifier();

// If this was a back-ticked identifier, drop the back-ticks.
if (str.size() >= 2 && str.front() == '`' && str.back() == '`') {
str = str.drop_front().drop_back();
}

return cContext.unbridged().getIdentifier(str);
return cContext.unbridged().getIdentifier(cStr.unbridged());
}

bool BridgedASTContext_langOptsHasFeature(BridgedASTContext cContext,
Expand Down Expand Up @@ -681,8 +672,7 @@ BridgedNominalTypeDecl BridgedProtocolDecl_createParsed(

auto primaryAssociatedTypeNames =
context.AllocateTransform<PrimaryAssociatedTypeName>(
cPrimaryAssociatedTypeNames
.unbridged<BridgedIdentifierAndSourceLoc>(),
cPrimaryAssociatedTypeNames.unbridged<BridgedLocatedIdentifier>(),
[](auto &e) -> PrimaryAssociatedTypeName {
return {e.Name.unbridged(), e.NameLoc.unbridged()};
});
Expand Down Expand Up @@ -781,15 +771,13 @@ BridgedPrecedenceGroupDecl BridgedPrecedenceGroupDecl_createParsed(
BridgedSourceLoc cRightBraceLoc) {

SmallVector<PrecedenceGroupDecl::Relation, 2> higherThanNames;
for (auto &pair :
cHigherThanNames.unbridged<BridgedIdentifierAndSourceLoc>()) {
for (auto &pair : cHigherThanNames.unbridged<BridgedLocatedIdentifier>()) {
higherThanNames.push_back(
{pair.NameLoc.unbridged(), pair.Name.unbridged(), nullptr});
}

SmallVector<PrecedenceGroupDecl::Relation, 2> lowerThanNames;
for (auto &pair :
cLowerThanNames.unbridged<BridgedIdentifierAndSourceLoc>()) {
for (auto &pair : cLowerThanNames.unbridged<BridgedLocatedIdentifier>()) {
lowerThanNames.push_back(
{pair.NameLoc.unbridged(), pair.Name.unbridged(), nullptr});
}
Expand All @@ -811,7 +799,7 @@ BridgedImportDecl BridgedImportDecl_createParsed(
BridgedSourceLoc cImportKindLoc, BridgedArrayRef cImportPathElements) {
ImportPath::Builder builder;
for (auto &element :
cImportPathElements.unbridged<BridgedIdentifierAndSourceLoc>()) {
cImportPathElements.unbridged<BridgedLocatedIdentifier>()) {
builder.push_back(element.Name.unbridged(), element.NameLoc.unbridged());
}

Expand Down
80 changes: 78 additions & 2 deletions lib/ASTGen/Sources/ASTGen/ASTGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import ASTBridging
import BasicBridging
import ParseBridging
// Needed to use BumpPtrAllocator
@_spi(BumpPtrAllocator) import SwiftSyntax
@_spi(BumpPtrAllocator) @_spi(RawSyntax) import SwiftSyntax

import struct SwiftDiagnostics.Diagnostic

Expand Down Expand Up @@ -106,7 +106,7 @@ struct ASTGenVisitor {
var out = [BridgedDecl]()

for element in node.statements {
let loc = element.bridgedSourceLoc(in: self)
let loc = self.generateSourceLoc(element)
let swiftASTNodes = generate(codeBlockItem: element)
switch swiftASTNodes {
case .decl(let d):
Expand Down Expand Up @@ -138,6 +138,82 @@ struct ASTGenVisitor {
}
}

extension ASTGenVisitor {
/// Obtains a bridged, `ASTContext`-owned "identifier".
///
/// If the token text is `_`, return an empty identifier. If the token is an
/// escaped identifier, backticks are stripped.
@inline(__always)
func generateIdentifier(_ token: TokenSyntax) -> BridgedIdentifier {
var text = token.rawText
// FIXME: Maybe `TokenSyntax.tokenView.rawKind == .wildcard`, or expose it as `.rawTokenKind`.
if text == "_" {
return nil
}
if text.count > 2 && text.hasPrefix("`") && text.hasSuffix("`") {
text = .init(rebasing: text.dropFirst().dropLast())
}
return self.ctx.getIdentifier(text.bridged)
}

/// Obtains a bridged, `ASTContext`-owned "identifier".
///
/// If the `token` text is `nil`, return an empty identifier.
@inline(__always)
func generateIdentifier(_ token: TokenSyntax?) -> BridgedIdentifier {
token.map(generateIdentifier(_:)) ?? nil
}

/// Obtains the start location of the node excluding leading trivia in the
/// source buffer.
@inline(__always)
func generateSourceLoc(_ node: some SyntaxProtocol) -> BridgedSourceLoc {
BridgedSourceLoc(at: node.positionAfterSkippingLeadingTrivia, in: self.base)
}

/// Obtains the start location of the node excluding leading trivia in the
/// source buffer. If the `node` is nil returns an invalid source location.
@inline(__always)
func generateSourceLoc(_ node: (some SyntaxProtocol)?) -> BridgedSourceLoc {
node.map(generateSourceLoc(_:)) ?? nil
}

/// Obtains a pair of bridged identifier and the bridged source location.
@inline(__always)
func generateIdentifierAndSourceLoc(_ token: TokenSyntax) -> (identifier: BridgedIdentifier, sourceLoc: BridgedSourceLoc) {
return (
self.generateIdentifier(token),
self.generateSourceLoc(token)
)
}

/// Obtains a pair of bridged identifier and the bridged source location.
/// If `token` is `nil`, returns a pair of an empty identifier and an invalid
/// source location.
@inline(__always)
func generateIdentifierAndSourceLoc(_ token: TokenSyntax?) -> (identifier: BridgedIdentifier, sourceLoc: BridgedSourceLoc) {
token.map(generateIdentifierAndSourceLoc(_:)) ?? (nil, nil)
}

/// Obtains a pair of bridged identifier and the bridged source location.
@inline(__always)
func generateLocatedIdentifier(_ token: TokenSyntax) -> BridgedLocatedIdentifier {
BridgedLocatedIdentifier(
name: self.generateIdentifier(token),
nameLoc: self.generateSourceLoc(token)
)
}

/// Obtains bridged token source range from a pair of token nodes.
@inline(__always)
func generateSourceRange(start: TokenSyntax, end: TokenSyntax) -> BridgedSourceRange {
BridgedSourceRange(
start: self.generateSourceLoc(start),
end: self.generateSourceLoc(end)
)
}
}

extension ASTGenVisitor {
/// Replaces the current declaration context with `declContext` for the duration of its execution, and calls `body`.
@inline(__always)
Expand Down
52 changes: 22 additions & 30 deletions lib/ASTGen/Sources/ASTGen/Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ public extension BridgedSourceLoc {
}
}

extension BridgedSourceRange {
@inline(__always)
init(startToken: TokenSyntax, endToken: TokenSyntax, in astgen: ASTGenVisitor) {
self.init(start: startToken.bridgedSourceLoc(in: astgen), end: endToken.bridgedSourceLoc(in: astgen))
}
}

extension String {
init(bridged: BridgedStringRef) {
self.init(
Expand Down Expand Up @@ -141,81 +134,80 @@ extension SyntaxProtocol {
/// Obtains the bridged start location of the node excluding leading trivia in the source buffer provided by `astgen`
///
/// - Parameter astgen: The visitor providing the source buffer.
@available(*, deprecated, message: "use ASTContext.bridgedSourceLoc(syntax:)")
@inline(__always)
func bridgedSourceLoc(in astgen: ASTGenVisitor) -> BridgedSourceLoc {
return BridgedSourceLoc(at: self.positionAfterSkippingLeadingTrivia, in: astgen.base)
astgen.generateSourceLoc(self)
}
}

extension Optional where Wrapped: SyntaxProtocol {
/// Obtains the bridged start location of the node excluding leading trivia in the source buffer provided by `astgen`.
///
/// - Parameter astgen: The visitor providing the source buffer.
@available(*, deprecated, message: "use ASTContext.bridgedSourceLoc(syntax:)")
@inline(__always)
func bridgedSourceLoc(in astgen: ASTGenVisitor) -> BridgedSourceLoc {
guard let self else {
return nil
}

return self.bridgedSourceLoc(in: astgen)
astgen.generateSourceLoc(self)
}
}

extension TokenSyntax {
/// Obtains a bridged, `ASTContext`-owned copy of this token's text.
///
/// - Parameter astgen: The visitor providing the `ASTContext`.
@available(*, deprecated, message: "use ASTContext.bridgedIdentifier(token:)")
@inline(__always)
func bridgedIdentifier(in astgen: ASTGenVisitor) -> BridgedIdentifier {
Comment on lines +159 to 161
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant "use ASTGenVisitor.generateIdentifier(_:)". Ditto other deprecations. Do we even need them though? It looks like you already audited all the calls.

var text = self.text
return text.withBridgedString { bridged in
astgen.ctx.getIdentifier(bridged)
}
astgen.generateIdentifier(self)
}

/// Obtains a bridged, `ASTContext`-owned copy of this token's text, and its bridged start location in the
/// source buffer provided by `astgen`.
///
/// - Parameter astgen: The visitor providing the `ASTContext` and source buffer.
@available(*, deprecated, message: "use ASTContext.bridgedIdentifierAndSourceLoc(token:)")
@inline(__always)
func bridgedIdentifierAndSourceLoc(in astgen: ASTGenVisitor) -> (BridgedIdentifier, BridgedSourceLoc) {
return (self.bridgedIdentifier(in: astgen), self.bridgedSourceLoc(in: astgen))
astgen.generateIdentifierAndSourceLoc(self)
}

/// Obtains a bridged, `ASTContext`-owned copy of this token's text, and its bridged start location in the
/// source buffer provided by `astgen`.
///
/// - Parameter astgen: The visitor providing the `ASTContext` and source buffer.
@available(*, deprecated, message: "use ASTContext.bridgedIdentifierAndSourceLoc(token:)")
@inline(__always)
func bridgedIdentifierAndSourceLoc(in astgen: ASTGenVisitor) -> BridgedIdentifierAndSourceLoc {
let (name, nameLoc) = self.bridgedIdentifierAndSourceLoc(in: astgen)
return .init(name: name, nameLoc: nameLoc)
func bridgedIdentifierAndSourceLoc(in astgen: ASTGenVisitor) -> BridgedLocatedIdentifier {
astgen.generateLocatedIdentifier(self)
}
}

extension Optional<TokenSyntax> {
/// Obtains a bridged, `ASTContext`-owned copy of this token's text.
///
/// - Parameter astgen: The visitor providing the `ASTContext`.
@available(*, deprecated, message: "use ASTContext.bridgedIdentifier(token:)")
@inline(__always)
func bridgedIdentifier(in astgen: ASTGenVisitor) -> BridgedIdentifier {
guard let self else {
return nil
}

return self.bridgedIdentifier(in: astgen)
astgen.generateIdentifier(self)
}

/// Obtains a bridged, `ASTContext`-owned copy of this token's text, and its bridged start location in the
/// source buffer provided by `astgen` excluding leading trivia.
///
/// - Parameter astgen: The visitor providing the `ASTContext` and source buffer.
@available(*, deprecated, message: "use ASTContext.bridgedIdentifierAndSourceLoc(token:)")
@inline(__always)
func bridgedIdentifierAndSourceLoc(in astgen: ASTGenVisitor) -> (BridgedIdentifier, BridgedSourceLoc) {
guard let self else {
return (nil, nil)
}
astgen.generateIdentifierAndSourceLoc(self)
}
}

return self.bridgedIdentifierAndSourceLoc(in: astgen)
extension BridgedSourceRange {
@available(*, deprecated, message: "use ASTContext.bridgedSourceRange(startToken:endToken:)")
@inline(__always)
init(startToken: TokenSyntax, endToken: TokenSyntax, in astgen: ASTGenVisitor) {
self = astgen.generateSourceRange(start: startToken, end: endToken)
}
}
Loading