Skip to content

Commit cb6372a

Browse files
committed
[ASTGen] Generate EditorPlaceholderExpr and 'do' expressions
1 parent b5a85ed commit cb6372a

File tree

7 files changed

+154
-15
lines changed

7 files changed

+154
-15
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,13 @@ BridgedDotSelfExpr BridgedDotSelfExpr_createParsed(BridgedASTContext cContext,
13211321
BridgedSourceLoc cDotLoc,
13221322
BridgedSourceLoc cSelfLoc);
13231323

1324+
SWIFT_NAME("BridgedEditorPlaceholderExpr.createParsed(_:placeholder:loc:"
1325+
"placeholderType:expansionType:)")
1326+
BridgedEditorPlaceholderExpr BridgedEditorPlaceholderExpr_createParsed(
1327+
BridgedASTContext cContext, BridgedIdentifier cPlaceholderId,
1328+
BridgedSourceLoc cLoc, BridgedNullableTypeRepr cPlaceholderTyR,
1329+
BridgedNullableTypeRepr cExpansionTyR);
1330+
13241331
SWIFT_NAME("BridgedErrorExpr.create(_:loc:)")
13251332
BridgedErrorExpr BridgedErrorExpr_create(BridgedASTContext cContext,
13261333
BridgedSourceRange cRange);

lib/AST/Bridging/ExprBridging.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,15 @@ BridgedDotSelfExpr BridgedDotSelfExpr_createParsed(BridgedASTContext cContext,
198198
cSubExpr.unbridged(), cDotLoc.unbridged(), cSelfLoc.unbridged());
199199
}
200200

201+
BridgedEditorPlaceholderExpr BridgedEditorPlaceholderExpr_createParsed(
202+
BridgedASTContext cContext, BridgedIdentifier cPlaceholderId,
203+
BridgedSourceLoc cLoc, BridgedNullableTypeRepr cPlaceholderTyR,
204+
BridgedNullableTypeRepr cExpansionTyR) {
205+
return new (cContext.unbridged()) EditorPlaceholderExpr(
206+
cPlaceholderId.unbridged(), cLoc.unbridged(), cPlaceholderTyR.unbridged(),
207+
cExpansionTyR.unbridged());
208+
}
209+
201210
BridgedErrorExpr BridgedErrorExpr_create(BridgedASTContext cContext,
202211
BridgedSourceRange cRange) {
203212
return new (cContext.unbridged()) ErrorExpr(cRange.unbridged());

lib/ASTGen/Sources/ASTGen/Exprs.swift

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import ASTBridging
1414
import SwiftDiagnostics
15+
@_spi(Compiler) import SwiftParser
1516
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax
1617

1718
/// Check if an `ExprSyntax` can be generated using ASTGen.
@@ -42,20 +43,18 @@ func isExprMigrated(_ node: ExprSyntax) -> Bool {
4243
// Known implemented kinds.
4344
case .asExpr, .arrayExpr, .arrowExpr, .assignmentExpr, .awaitExpr, .binaryOperatorExpr,
4445
.booleanLiteralExpr, .borrowExpr, .closureExpr, .consumeExpr, .copyExpr,
45-
.discardAssignmentExpr, .declReferenceExpr, .dictionaryExpr, .floatLiteralExpr,
46-
.functionCallExpr, .ifExpr,
47-
.infixOperatorExpr, .inOutExpr, .integerLiteralExpr, .memberAccessExpr,
46+
.discardAssignmentExpr, .declReferenceExpr, .dictionaryExpr, .doExpr,
47+
.editorPlaceholderExpr, .floatLiteralExpr, .functionCallExpr, .genericSpecializationExpr,
48+
.ifExpr, .infixOperatorExpr, .inOutExpr, .integerLiteralExpr, .isExpr, .memberAccessExpr,
4849
.nilLiteralExpr, .packElementExpr, .packExpansionExpr, .patternExpr,
4950
.postfixOperatorExpr, .prefixOperatorExpr, .regexLiteralExpr, .sequenceExpr,
5051
.simpleStringLiteralExpr, .subscriptCallExpr, .stringLiteralExpr, .superExpr,
51-
.tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr,
52+
.switchExpr, .tryExpr, .tupleExpr, .typeExpr, .unresolvedAsExpr, .unresolvedIsExpr,
5253
.unresolvedTernaryExpr, .ternaryExpr:
5354
break
5455

5556
// Known unimplemented kinds.
56-
case .doExpr, .editorPlaceholderExpr, .forceUnwrapExpr, .isExpr, .keyPathExpr, .macroExpansionExpr,
57-
.optionalChainingExpr, .postfixIfConfigExpr, .genericSpecializationExpr,
58-
.switchExpr:
57+
case .forceUnwrapExpr, .keyPathExpr, .macroExpansionExpr, .optionalChainingExpr, .postfixIfConfigExpr:
5958
return false
6059

6160
// Unknown expr kinds.
@@ -102,15 +101,15 @@ extension ASTGenVisitor {
102101
case .copyExpr(let node):
103102
return self.generate(copyExpr: node).asExpr
104103
case .declReferenceExpr(let node):
105-
return self.generate(declReferenceExpr: node).asExpr
104+
return self.generate(declReferenceExpr: node)
106105
case .dictionaryExpr(let node):
107106
return self.generate(dictionaryExpr: node).asExpr
108107
case .discardAssignmentExpr(let node):
109108
return self.generate(discardAssignmentExpr: node).asExpr
110-
case .doExpr:
111-
break
109+
case .doExpr(let node):
110+
return self.generate(doExpr: node).asExpr
112111
case .editorPlaceholderExpr:
113-
break
112+
preconditionFailure("EditorPlaceholderExpr is no longer generated by the parser")
114113
case .floatLiteralExpr(let node):
115114
return self.generate(floatLiteralExpr: node).asExpr
116115
case .forceUnwrapExpr:
@@ -128,7 +127,7 @@ extension ASTGenVisitor {
128127
case .integerLiteralExpr(let node):
129128
return self.generate(integerLiteralExpr: node).asExpr
130129
case .isExpr:
131-
break
130+
preconditionFailure("IsExprSyntax only appear after operator folding")
132131
case .keyPathExpr:
133132
break
134133
case .macroExpansionExpr:
@@ -428,20 +427,67 @@ extension ASTGenVisitor {
428427
}
429428
}
430429

431-
func generate(declReferenceExpr node: DeclReferenceExprSyntax) -> BridgedUnresolvedDeclRefExpr {
432-
let nameAndLoc = generateDeclNameRef(declReferenceExpr: node)
430+
func generateEditorPlaceholderExpr(token: TokenSyntax) -> BridgedEditorPlaceholderExpr {
431+
guard let data = token.rawEditorPlaceHolderData else {
432+
preconditionFailure("EditorPlaceholderExprSyntax.placeholder must be a placeholder token")
433+
}
434+
let (identifier, loc) = self.generateIdentifierAndSourceLoc(token)
435+
let placeholderTyR: BridgedTypeRepr?
436+
let expansionTyR: BridgedTypeRepr?
437+
func parseType(text: SyntaxText) -> BridgedTypeRepr {
438+
var parser = Parser(UnsafeBufferPointer(start: text.baseAddress, count: text.count))
439+
let syntax = TypeSyntax.parse(from: &parser)
440+
return self.generate(type: syntax)
441+
}
442+
if let typeText = data.typeText {
443+
placeholderTyR = parseType(text: typeText)
444+
} else {
445+
placeholderTyR = nil
446+
}
447+
if data.typeText == data.typeForExpansionText {
448+
expansionTyR = placeholderTyR
449+
} else {
450+
// `typeForExpansionText` is guaranteed to be non-nil if `typeText` is non-nil,
451+
expansionTyR = parseType(text: data.typeForExpansionText!)
452+
}
433453
return .createParsed(
454+
self.ctx,
455+
placeholder: identifier,
456+
loc: loc,
457+
placeholderType: placeholderTyR.asNullable,
458+
expansionType: expansionTyR.asNullable
459+
)
460+
}
461+
462+
func generate(declReferenceExpr node: DeclReferenceExprSyntax) -> BridgedExpr {
463+
if node.baseName.isEditorPlaceholder {
464+
return generateEditorPlaceholderExpr(token: node.baseName).asExpr
465+
}
466+
let nameAndLoc = generateDeclNameRef(declReferenceExpr: node)
467+
return BridgedUnresolvedDeclRefExpr.createParsed(
434468
self.ctx,
435469
name: nameAndLoc.name,
436470
kind: .ordinary,
437471
loc: nameAndLoc.loc
438-
)
472+
).asExpr
439473
}
440474

441475
func generate(discardAssignmentExpr node: DiscardAssignmentExprSyntax) -> BridgedDiscardAssignmentExpr {
442476
return .createParsed(self.ctx, loc: self.generateSourceLoc(node.wildcard))
443477
}
444478

479+
func generate(doExpr node: DoExprSyntax) -> BridgedSingleValueStmtExpr {
480+
let stmt = self.generate(doStmtOrExpr: node)
481+
482+
// Wrap in a SingleValueStmtExpr to embed as an expression.
483+
return .createWithWrappedBranches(
484+
ctx,
485+
stmt: stmt,
486+
declContext: declContext,
487+
mustBeExpr: true
488+
)
489+
}
490+
445491
func generate(memberAccessExpr node: MemberAccessExprSyntax) -> BridgedExpr {
446492
let dotLoc = self.generateSourceLoc(node.period)
447493
let nameAndLoc = generateDeclNameRef(declReferenceExpr: node.declName)

lib/ASTGen/Sources/ASTGen/Stmts.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ import ASTBridging
1414
import SwiftDiagnostics
1515
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
1616

17+
protocol DoStmtOrExprSyntax {
18+
var doKeyword: TokenSyntax { get }
19+
var throwsClause: ThrowsClauseSyntax? { get }
20+
var body: CodeBlockSyntax { get }
21+
var catchClauses: CatchClauseListSyntax { get }
22+
}
23+
extension DoStmtSyntax: DoStmtOrExprSyntax {}
24+
extension DoExprSyntax: DoStmtOrExprSyntax {
25+
// FIXME: DoExprSyntax is missing throwsClause?
26+
var throwsClause: ThrowsClauseSyntax? { return nil }
27+
}
28+
1729
extension ASTGenVisitor {
1830
func generate(stmt node: StmtSyntax) -> BridgedStmt {
1931
switch node.as(StmtSyntaxEnum.self) {
@@ -262,6 +274,13 @@ extension ASTGenVisitor {
262274
}
263275

264276
func generate(doStmt node: DoStmtSyntax, labelInfo: BridgedLabeledStmtInfo = nil) -> BridgedStmt {
277+
return self.generate(doStmtOrExpr: node, labelInfo: labelInfo)
278+
}
279+
280+
func generate(
281+
doStmtOrExpr node: some DoStmtOrExprSyntax,
282+
labelInfo: BridgedLabeledStmtInfo = nil
283+
) -> BridgedStmt {
265284
if node.catchClauses.isEmpty {
266285
// FIXME: Handle
267286
precondition(node.throwsClause == nil)

lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,9 +356,11 @@ void Parser::parseSourceFileViaASTGen(
356356
appendToVector);
357357

358358
// Spin the C++ parser to the end; we won't be using it.
359+
DiagnosticTransaction noDiag(Context.Diags);
359360
while (!Tok.is(tok::eof)) {
360361
consumeToken();
361362
}
363+
noDiag.abort();
362364
}
363365
#endif
364366
}

test/ASTGen/diagnostics.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: not %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-bare-slash-regex -enable-experimental-feature ParserASTGen > %t/astgen.ast.raw
4+
// RUN: not %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-bare-slash-regex > %t/cpp-parser.ast.raw
5+
6+
// Filter out any addresses in the dump, since they can differ.
7+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/cpp-parser.ast.raw > %t/cpp-parser.ast
8+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/astgen.ast.raw > %t/astgen.ast
9+
10+
// RUN: %diff -u %t/astgen.ast %t/cpp-parser.ast
11+
12+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-bare-slash-regex -enable-experimental-feature ParserASTGen
13+
14+
// REQUIRES: swift_swift_parser
15+
// -enable-experimental-feature requires an asserts build
16+
// REQUIRES: asserts
17+
// rdar://116686158
18+
// UNSUPPORTED: asan
19+
20+
func testRegexLiteral() {
21+
_ = (#/[*/#, #/+]/#, #/.]/#)
22+
// expected-error@-1:18 {{cannot parse regular expression: quantifier '+' must appear after expression}}
23+
// expected-error@-2:12 {{cannot parse regular expression: expected ']'}}
24+
}
25+
26+
func testEditorPlaceholder() -> Int {
27+
func foo(_ x: String) {}
28+
foo(<#T##x: String##String#>) // expected-error {{editor placeholder in source file}})
29+
return <#T##Int#> // expected-error {{editor placeholder in source file}}
30+
}

test/ASTGen/do_expr.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-experimental-feature DoExpressions -enable-experimental-feature ParserASTGen > %t/astgen.ast.raw
4+
// RUN: %target-swift-frontend %s -dump-parse -disable-availability-checking -enable-experimental-feature DoExpressions > %t/cpp-parser.ast.raw
5+
6+
// Filter out any addresses in the dump, since they can differ.
7+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/cpp-parser.ast.raw > %t/cpp-parser.ast
8+
// RUN: sed -E 's#0x[0-9a-fA-F]+##g' %t/astgen.ast.raw > %t/astgen.ast
9+
10+
// RUN: %diff -u %t/astgen.ast %t/cpp-parser.ast
11+
12+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature DoExpressions -enable-experimental-feature ParserASTGen
13+
14+
// REQUIRES: swift_swift_parser
15+
// -enable-experimental-feature requires an asserts build
16+
// REQUIRES: asserts
17+
// rdar://116686158
18+
// UNSUPPORTED: asan
19+
20+
func fn() async throws -> Int { 6 }
21+
struct Err: Error {}
22+
23+
func testDoExpr() async throws {
24+
let _: Int = do { 5 }
25+
let _: Int = do { try await fn() } catch { throw Err() }
26+
}

0 commit comments

Comments
 (0)