Skip to content

Commit

Permalink
[ASTGen] Generate CaptureListExpr
Browse files Browse the repository at this point in the history
Move the capture list entry construction logic to
CaptureListEntry::createParsed() so that ASTGen can use it.
  • Loading branch information
rintaro committed Feb 16, 2025
1 parent 44c1bf7 commit 9deaa80
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 41 deletions.
36 changes: 36 additions & 0 deletions include/swift/AST/ASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class AvailabilityDomain;
class Argument;
class ASTContext;
struct ASTNode;
struct CaptureListEntry;
class DeclAttributes;
class DeclBaseName;
class DeclNameLoc;
Expand All @@ -55,6 +56,7 @@ enum class PlatformKind : uint8_t;
class ProtocolConformanceRef;
class RegexLiteralPatternFeature;
class RegexLiteralPatternFeatureKind;
enum class ReferenceOwnership : uint8_t;
class Type;
class CanType;
class TypeBase;
Expand Down Expand Up @@ -114,6 +116,10 @@ inline const void *_Nullable BridgedIdentifier_raw(BridgedIdentifier ident) {
return ident.Raw;
}

SWIFT_NAME("getter:BridgedIdentifier.str(self:)")
BRIDGED_INLINE BridgedStringRef
BridgedIdentifier_getStr(BridgedIdentifier ident);

SWIFT_NAME("getter:BridgedIdentifier.isOperator(self:)")
BRIDGED_INLINE bool BridgedIdentifier_isOperator(const BridgedIdentifier);

Expand Down Expand Up @@ -1104,11 +1110,14 @@ BridgedRawDocCommentAttr_createParsed(BridgedASTContext cContext,
BridgedCharSourceRange cRange);

enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedReferenceOwnership {
BridgedReferenceOwnershipStrong,
BridgedReferenceOwnershipWeak,
BridgedReferenceOwnershipUnowned,
BridgedReferenceOwnershipUnmanaged,
};

swift::ReferenceOwnership unbridged(BridgedReferenceOwnership kind);

SWIFT_NAME("BridgedReferenceOwnershipAttr.createParsed(_:atLoc:range:kind:)")
BridgedReferenceOwnershipAttr BridgedReferenceOwnershipAttr_createParsed(
BridgedASTContext cContext, BridgedSourceLoc cAtLoc,
Expand Down Expand Up @@ -1625,6 +1634,33 @@ BridgedCallExpr BridgedCallExpr_createParsed(BridgedASTContext cContext,
BridgedExpr fn,
BridgedArgumentList args);

class BridgedCaptureListEntry {
swift::PatternBindingDecl *_Nonnull PBD;

public:
BRIDGED_INLINE BridgedCaptureListEntry(swift::CaptureListEntry CLE);

BRIDGED_INLINE swift::CaptureListEntry unbridged() const;
};

SWIFT_NAME("BridgedCaptureListEntry.createParsed(_:declContext:ownership:"
"ownershipRange:name:nameLoc:equalLoc:initializer:)")
BridgedCaptureListEntry BridegedCaptureListEntry_createParsed(
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
BridgedReferenceOwnership cOwnershipKind,
BridgedSourceRange cOwnershipRange, BridgedIdentifier cName,
BridgedSourceLoc cNameLoc, BridgedSourceLoc cEqualLoc,
BridgedExpr cInitializer);

SWIFT_NAME("getter:BridgedCaptureListEntry.varDecl(self:)")
BRIDGED_INLINE BridgedVarDecl
BridegedCaptureListEntry_getVar(BridgedCaptureListEntry entry);

SWIFT_NAME("BridgedCaptureListExpr.createParsed(_:captureList:closure:)")
BridgedCaptureListExpr BridgedCaptureListExpr_createParsed(BridgedASTContext cContext,
BridgedArrayRef cCaptureList,
BridgedClosureExpr cClosure);

SWIFT_NAME("BridgedClosureExpr.createParsed(_:declContext:attributes:"
"bracketRange:capturedSelfDecl:parameterList:asyncLoc:throwsLoc:"
"thrownType:arrowLoc:explicitResultType:inLoc:)")
Expand Down
19 changes: 18 additions & 1 deletion include/swift/AST/ASTBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ swift::Identifier BridgedIdentifier::unbridged() const {
return swift::Identifier::getFromOpaquePointer(Raw);
}

SWIFT_NAME("getter:BridgedIdentifier.isOperator(self:)")
BridgedStringRef BridgedIdentifier_getStr(const BridgedIdentifier ident) {
return ident.unbridged().str();
}

bool BridgedIdentifier_isOperator(const BridgedIdentifier ident) {
return ident.unbridged().isOperator();
}
Expand Down Expand Up @@ -629,6 +632,20 @@ swift::StmtConditionElement BridgedStmtConditionElement::unbridged() const {
return swift::StmtConditionElement::fromOpaqueValue(Raw);
}

//===----------------------------------------------------------------------===//
// MARK: BridgedCaptureListEntry
//===----------------------------------------------------------------------===//

BridgedCaptureListEntry::BridgedCaptureListEntry(swift::CaptureListEntry CLE)
: PBD(CLE.PBD) {}

swift::CaptureListEntry BridgedCaptureListEntry::unbridged() const {
return swift::CaptureListEntry(PBD);
}

BridgedVarDecl BridegedCaptureListEntry_getVar(BridgedCaptureListEntry entry) {
return entry.unbridged().getVar();
}

SWIFT_END_NULLABILITY_ANNOTATIONS

Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -4562,6 +4562,11 @@ struct CaptureListEntry {

explicit CaptureListEntry(PatternBindingDecl *PBD);

static CaptureListEntry
createParsed(ASTContext &Ctx, ReferenceOwnership ownershipKind,
SourceRange ownershipRange, Identifier name, SourceLoc nameLoc,
SourceLoc equalLoc, Expr *initializer, DeclContext *DC);

VarDecl *getVar() const;
bool isSimpleSelfCapture(bool excludeWeakCaptures = true) const;
};
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/BasicBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ BRIDGED_INLINE SwiftInt BridgedStringRef_count(BridgedStringRef str);
SWIFT_NAME("getter:BridgedStringRef.isEmpty(self:)")
BRIDGED_INLINE bool BridgedStringRef_empty(BridgedStringRef str);

SWIFT_NAME("BridgedStringRef.equals(self:_:)")
BRIDGED_INLINE bool BridgedStringRef_equals(BridgedStringRef lhs,
BridgedStringRef rhs);

class BridgedOwnedString {
char *_Nonnull Data;
size_t Length;
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/BasicBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ bool BridgedStringRef_empty(BridgedStringRef str) {
return str.unbridged().empty();
}

bool BridgedStringRef_equals(BridgedStringRef lhs, BridgedStringRef rhs) {
return lhs.unbridged() == rhs.unbridged();
}

//===----------------------------------------------------------------------===//
// MARK: BridgedOwnedString
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 3 additions & 1 deletion lib/AST/Bridging/DeclAttributeBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,10 @@ BridgedRawDocCommentAttr_createParsed(BridgedASTContext cContext,
return new (cContext.unbridged()) RawDocCommentAttr(cRange.unbridged());
}

static ReferenceOwnership unbridged(BridgedReferenceOwnership kind) {
ReferenceOwnership unbridged(BridgedReferenceOwnership kind) {
switch (kind) {
case BridgedReferenceOwnershipStrong:
return ReferenceOwnership::Strong;
case BridgedReferenceOwnershipWeak:
return ReferenceOwnership::Weak;
case BridgedReferenceOwnershipUnowned:
Expand Down
25 changes: 25 additions & 0 deletions lib/AST/Bridging/ExprBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,31 @@ BridgedCallExpr BridgedCallExpr_createParsed(BridgedASTContext cContext,
/*implicit*/ false);
}

BridgedCaptureListEntry BridegedCaptureListEntry_createParsed(
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
BridgedReferenceOwnership cOwnershipKind,
BridgedSourceRange cOwnershipRange, BridgedIdentifier cName,
BridgedSourceLoc cNameLoc, BridgedSourceLoc cEqualLoc,
BridgedExpr cInitializer) {
return CaptureListEntry::createParsed(
cContext.unbridged(), unbridged(cOwnershipKind),
cOwnershipRange.unbridged(), cName.unbridged(), cNameLoc.unbridged(),
cEqualLoc.unbridged(), cInitializer.unbridged(),
cDeclContext.unbridged());
}

BridgedCaptureListExpr
BridgedCaptureListExpr_createParsed(BridgedASTContext cContext,
BridgedArrayRef cCaptureList,
BridgedClosureExpr cClosure) {
SmallVector<CaptureListEntry, 4> captureList;
for (auto e : cCaptureList.unbridged<BridgedCaptureListEntry>())
captureList.push_back(e.unbridged());

return CaptureListExpr::create(cContext.unbridged(), captureList,
cClosure.unbridged());
}

BridgedClosureExpr BridgedClosureExpr_createParsed(
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
BridgedDeclAttributes cAttributes, BridgedSourceRange cBracketRange,
Expand Down
28 changes: 28 additions & 0 deletions lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,34 @@ CaptureListEntry::CaptureListEntry(PatternBindingDecl *PBD) : PBD(PBD) {
"Capture lists only support single-var patterns");
}

CaptureListEntry CaptureListEntry::createParsed(
ASTContext &Ctx, ReferenceOwnership ownershipKind,
SourceRange ownershipRange, Identifier name, SourceLoc nameLoc,
SourceLoc equalLoc, Expr *initializer, DeclContext *DC) {

auto introducer =
(ownershipKind != ReferenceOwnership::Weak ? VarDecl::Introducer::Let
: VarDecl::Introducer::Var);
auto *VD =
new (Ctx) VarDecl(/*isStatic==*/false, introducer, nameLoc, name, DC);

if (ownershipKind != ReferenceOwnership::Strong)
VD->getAttrs().add(
new (Ctx) ReferenceOwnershipAttr(ownershipRange, ownershipKind));

auto *pattern = NamedPattern::createImplicit(Ctx, VD);

auto *PBD = PatternBindingDecl::create(Ctx, /*StaticLoc=*/SourceLoc(),
StaticSpellingKind::None, nameLoc,
pattern, equalLoc, initializer, DC);
CaptureListEntry CLE(PBD);

if (CLE.isSimpleSelfCapture())
VD->setIsSelfParamCapture();

return CLE;
}

VarDecl *CaptureListEntry::getVar() const {
return PBD->getSingleVar();
}
Expand Down
6 changes: 6 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Bridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ extension BridgedStringRef: /*@retroactive*/ Swift.ExpressibleByStringLiteral {
}
}

extension BridgedStringRef: /*@retroactive*/ Swift.Equatable {
public static func ==(lhs: BridgedStringRef, rhs: BridgedStringRef) -> Bool {
lhs.equals(rhs)
}
}

extension VersionTuple {
var bridged: BridgedVersionTuple {
switch self.components.count {
Expand Down
78 changes: 65 additions & 13 deletions lib/ASTGen/Sources/ASTGen/Exprs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extension ASTGenVisitor {
case .borrowExpr(let node):
return self.generate(borrowExpr: node).asExpr
case .closureExpr(let node):
return self.generate(closureExpr: node).asExpr
return self.generate(closureExpr: node)
case .consumeExpr(let node):
return self.generate(consumeExpr: node).asExpr
case .copyExpr(let node):
Expand Down Expand Up @@ -219,7 +219,7 @@ extension ASTGenVisitor {
}

func generate(binaryOperatorExpr node: BinaryOperatorExprSyntax) -> BridgedUnresolvedDeclRefExpr {
return createOperatorRefExpr(token: node.operator, kind: .binaryOperator)
return createUnresolvedDeclRefExpr(token: node.operator, kind: .binaryOperator)
}

func generate(closureSignature node: ClosureSignatureSyntax) -> GeneratedClosureSignature {
Expand All @@ -233,7 +233,7 @@ extension ASTGenVisitor {
if let node = node.capture {
result.bracketRange = self.generateSourceRange(node)
let captures = node.items.lazy.map { node in
self.generate(closureCapture: node)
self.generate(closureCapture: node, capturedSelfDecl: &result.capturedSelfDecl)
}
result.captureList = captures.bridgedArray(in: self)
}
Expand Down Expand Up @@ -268,8 +268,56 @@ extension ASTGenVisitor {
return result
}

func generate(closureCapture node: ClosureCaptureSyntax) {
fatalError("unimplemented")
func generate(closureCapture node: ClosureCaptureSyntax, capturedSelfDecl: inout BridgedVarDecl?) -> BridgedCaptureListEntry {
let ownership: BridgedReferenceOwnership
switch node.specifier?.specifier.rawText {
case nil:
ownership = .strong
case "weak":
ownership = .weak
case "unowned":
switch node.specifier?.detail?.rawText {
case nil, "safe":
ownership = .unowned
case "unsafe":
ownership = .unmanaged
default:
// TODO: Diagnose.
fatalError("invalid ownership")
}
default:
// TODO: Diagnose.
fatalError("invalid ownership")
}
let nameAndLoc = self.generateIdentifierAndSourceLoc(node.name)
let equalLoc: BridgedSourceLoc
let initExpr: BridgedExpr
if let initializer = node.initializer {
equalLoc = self.generateSourceLoc(initializer.equal)
initExpr = self.generate(expr: initializer.value)
} else {
// Otherwise, create an 'UnresolvedDeclRefExpr' with the name
equalLoc = nil
initExpr = self.createUnresolvedDeclRefExpr(token: node.name, kind: .ordinary).asExpr
}

let entry = BridgedCaptureListEntry.createParsed(
self.ctx,
declContext: self.declContext,
ownership: ownership,
ownershipRange: self.generateSourceRange(node.specifier),
name: nameAndLoc.identifier,
nameLoc: nameAndLoc.sourceLoc,
equalLoc: equalLoc,
initializer: initExpr
)

// If we captured something under the name "self", remember that.
if nameAndLoc.identifier.str == "self" {
capturedSelfDecl = entry.varDecl
}

return entry
}

struct GeneratedClosureSignature {
Expand All @@ -286,7 +334,7 @@ extension ASTGenVisitor {
var inLoc: BridgedSourceLoc = nil
}

func generate(closureExpr node: ClosureExprSyntax) -> BridgedClosureExpr {
func generate(closureExpr node: ClosureExprSyntax) -> BridgedExpr {
let signature: GeneratedClosureSignature
if let node = node.signature {
signature = self.generate(closureSignature: node)
Expand Down Expand Up @@ -353,10 +401,14 @@ extension ASTGenVisitor {
expr.setBody(body)

if signature.captureList.count > 0 {
// TODO: CaptureListExpr.
return BridgedCaptureListExpr.createParsed(
self.ctx,
captureList: signature.captureList,
closure: expr
).asExpr
}

return expr
return expr.asExpr
}

func generate(consumeExpr node: ConsumeExprSyntax) -> BridgedConsumeExpr {
Expand Down Expand Up @@ -414,7 +466,7 @@ extension ASTGenVisitor {
let bridgedTrailingClosureArg = BridgedCallArgument(
labelLoc: nil,
label: nil,
argExpr: self.generate(closureExpr: trailingClosure).asExpr
argExpr: self.generate(closureExpr: trailingClosure)
)
let normalArgsAndClosure = ConcatCollection(normalArgs, CollectionOfOne(bridgedTrailingClosureArg))
guard let additionalTrailingClosures else {
Expand All @@ -426,7 +478,7 @@ extension ASTGenVisitor {
return BridgedCallArgument(
labelLoc: self.generateSourceLoc(argNode.label),
label: self.generateIdentifier(argNode.label),
argExpr: self.generate(closureExpr: argNode.closure).asExpr
argExpr: self.generate(closureExpr: argNode.closure)
)
}
let allArgs = ConcatCollection(normalArgsAndClosure, additions)
Expand Down Expand Up @@ -1044,7 +1096,7 @@ extension ASTGenVisitor {
let operand = self.generate(expr: node.expression, postfixIfConfigBaseExpr: postfixIfConfigBaseExpr)
return .createParsed(
self.ctx,
operator: self.createOperatorRefExpr(
operator: self.createUnresolvedDeclRefExpr(
token: node.operator,
kind: .postfixOperator
).asExpr,
Expand All @@ -1055,7 +1107,7 @@ extension ASTGenVisitor {
func generate(prefixOperatorExpr node: PrefixOperatorExprSyntax) -> BridgedPrefixUnaryExpr {
return .createParsed(
self.ctx,
operator: self.createOperatorRefExpr(
operator: self.createUnresolvedDeclRefExpr(
token: node.operator,
kind: .prefixOperator
).asExpr,
Expand Down Expand Up @@ -1294,7 +1346,7 @@ extension ASTGenVisitor {
}

extension ASTGenVisitor {
fileprivate func createOperatorRefExpr(
fileprivate func createUnresolvedDeclRefExpr(
token node: TokenSyntax,
kind: BridgedDeclRefKind
) -> BridgedUnresolvedDeclRefExpr {
Expand Down
Loading

0 comments on commit 9deaa80

Please sign in to comment.