Skip to content

[ASTGen] Introduce wrapper types for AST nodes #69229

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 5 commits into from
Oct 21, 2023

Conversation

hamishknight
Copy link
Contributor

@hamishknight hamishknight commented Oct 17, 2023

Stamp out wrapper types for all the AST nodes, and use them for ASTGen, with members being imported on those types.

Resolves #68346
Resolves #68348
rdar://117159010

@hamishknight hamishknight changed the title [DNM] C wrappers for ASTGen [ASTGen] Introduce wrapper types for AST nodes Oct 20, 2023
@hamishknight hamishknight marked this pull request as ready for review October 20, 2023 10:32
@hamishknight
Copy link
Contributor Author

@swift-ci please test

@hamishknight
Copy link
Contributor Author

hamishknight commented Oct 20, 2023

@ahoppen For #68348 my preference is to import as static members since this would make it easier to switch to C++ interop (I suppose we could import as initializers with C++ interop too, but I don't think we should favor createParsed over other static creation methods since eventually we'll likely want to be able to use other createXXX methods from Swift).

@hamishknight hamishknight added the ASTGen Area → compiler: The ASTGen module, which translates SwiftSyntax trees to the C++ AST label Oct 20, 2023
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

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

Soooo much nicer. Thank you!

A couple of ideas to improve things further inline but as far as I’m concerned nothing that’s blocking us from merging the PR.

Comment on lines 47 to 53
static inline BridgedDeclContext bridgedDeclContext(DeclContext *declContext) {
return {declContext};
}

static inline DeclContext *unbridged(BridgedDeclContext cDeclContext) {
return static_cast<DeclContext *>(cDeclContext.raw);
}
Copy link
Member

Choose a reason for hiding this comment

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

In Swift, these would make wonderful extensions on BridgedDeclContext and DeclContext. A shame we don’t have type extensions in C++. 😢

Comment on lines -40 to +52
return BridgedASTNode(ptr: e, kind: .expr)
return BridgedASTNode(ptr: e.raw!, kind: .expr)
Copy link
Member

Choose a reason for hiding this comment

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

Should we create a BridgedASTNode with a nullptr instead of crashing here? AFAICT nothing guarantees that raw is not nil here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BridgedASTNode has a non-nullable value, so we have to unwrap here. We could change BridgedASTNode to take a nullable value, but that would just be trading an explicit unwrap for an implicit null pointer access in C++ land. The alternative here would be to introduce separate nullable types for the base AST node wrapper types, e.g BridgedExpr and BridgedNullableExpr, and then parameters expecting a nullable expr could use the nullable version and you'd have to add an extra .init(...) when passing the argument. I can't say I'm a huge fan of that, though I do agree the force unwrap here isn't great.

Copy link
Member

Choose a reason for hiding this comment

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

Or a completely different option: Do you think we actually need ASTNode or could we remove it altogether (definitely not this PR). To me ASTNode seems like an anti-pattern anyway because it generalizes too much.

For example ASTGen.generate(ExprSyntax) should switch over all the expression nodes (for which we need to implement an ExprSyntaxEnum, which I think I have thought about adding for 2 years now) and then it could just return a BridgedExprSyntax without the need to go through ASTNode.

Copy link
Contributor Author

@hamishknight hamishknight Oct 20, 2023

Choose a reason for hiding this comment

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

The issue is for things like BraceStmt, where the elements truly are ASTNodes :/ AFAIK that's actually the only place this logic is currently used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FWIW this is what it would look like with nullable wrappers ef74078, I guess it's not too bad? Still can't say I love it

Copy link
Member

Choose a reason for hiding this comment

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

I think I prefer it with ef74078. At least it’s explicit about what it’s doing and the asNullable are annoying but not toooo bad. But it’s Friday evening and I might change my mind when I look at this again on Monday.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I don't really have particulary strong feelings either way, I've left it as-is for now, but am happy to do the nullable wrappers in a follow up

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm the more I think about, the less I hate it, put up a PR: #69326

This is for decl nodes that are both abstract and
are DeclContexts.
Stamp out wrapper types for all the AST nodes,
and use them for ASTGen, with members being
imported on those types.
This is consistent with the AST node bridging
naming scheme and IMO the old names were
needlessly verbose.
@hamishknight
Copy link
Contributor Author

@swift-ci please test

@hamishknight hamishknight merged commit 11b8549 into swiftlang:main Oct 21, 2023
@hamishknight hamishknight deleted the boxing-match branch October 21, 2023 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ASTGen Area → compiler: The ASTGen module, which translates SwiftSyntax trees to the C++ AST
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change NilLiteralExpr_create to NilLiteralExpr.init etc. Remove usages of void * in CASTBridging.h
2 participants