Skip to content

Commit b399173

Browse files
authored
Merge pull request #69761 from rintaro/astgen-incremental-develop
[ASTGen] Infrastructure for implementing ASTGen incrementally
2 parents bb5fd84 + d51058c commit b399173

24 files changed

+869
-235
lines changed

include/module.modulemap

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ module ASTBridging {
1010
export *
1111
}
1212

13+
module ParseBridging {
14+
header "swift/Parse/ParseBridging.h"
15+
requires cplusplus
16+
export *
17+
}
18+
1319
module SILBridging {
1420
header "swift/SIL/SILBridging.h"
1521
requires cplusplus

include/swift/AST/ASTBridgingWrappers.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@
5959
// optional parameters.
6060
AST_BRIDGING_WRAPPER_NONNULL(Decl)
6161
AST_BRIDGING_WRAPPER_NONNULL(DeclContext)
62+
AST_BRIDGING_WRAPPER_NONNULL(SourceFile)
6263
AST_BRIDGING_WRAPPER_NULLABLE(Stmt)
6364
AST_BRIDGING_WRAPPER_NULLABLE(Expr)
65+
AST_BRIDGING_WRAPPER_NULLABLE(Pattern)
6466
AST_BRIDGING_WRAPPER_NULLABLE(TypeRepr)
6567

6668
// Misc AST types to generate wrappers for.

include/swift/Basic/Features.def

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,6 @@ EXPERIMENTAL_FEATURE(ImplicitSome, false)
193193
/// corresponding syntax tree.
194194
EXPERIMENTAL_FEATURE(ParserASTGen, false)
195195

196-
/// Use the syntax tree produced by the Swift (swift-syntax) parser for type
197-
/// parsing, using ASTGen to translate them into AST nodes.
198-
EXPERIMENTAL_FEATURE(ASTGenTypes, false)
199-
200196
/// Parse using the Swift (swift-syntax) parser and use ASTGen to generate the
201197
/// corresponding syntax tree.
202198
EXPERIMENTAL_FEATURE(BuiltinMacros, false)

include/swift/Bridging/ASTGen.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/AST/ASTBridging.h"
14+
#include "swift/Parse/ParseBridging.h"
1415

1516
#ifdef __cplusplus
1617
extern "C" {
@@ -40,6 +41,23 @@ void *_Nullable swift_ASTGen_parseSourceFile(const char *_Nonnull buffer,
4041
void *_Nullable ctx);
4142
void swift_ASTGen_destroySourceFile(void *_Nonnull sourceFile);
4243

44+
/// Check whether the given source file round-trips correctly. Returns 0 if
45+
/// round-trip succeeded, non-zero otherwise.
46+
int swift_ASTGen_roundTripCheck(void *_Nonnull sourceFile);
47+
48+
/// Emit parser diagnostics for given source file.. Returns non-zero if any
49+
/// diagnostics were emitted.
50+
int swift_ASTGen_emitParserDiagnostics(
51+
void *_Nonnull diagEngine, void *_Nonnull sourceFile, int emitOnlyErrors,
52+
int downgradePlaceholderErrorsToWarnings);
53+
54+
// Build AST nodes for the top-level entities in the syntax.
55+
void swift_ASTGen_buildTopLevelASTNodes(
56+
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
57+
BridgedDeclContext declContext, BridgedASTContext astContext,
58+
BridgedLegacyParser legacyParser, void *_Nonnull outputContext,
59+
void (*_Nonnull)(void *_Nonnull, void *_Nonnull));
60+
4361
void *_Nullable swift_ASTGen_resolveMacroType(const void *_Nonnull macroType);
4462
void swift_ASTGen_destroyMacro(void *_Nonnull macro);
4563

@@ -84,6 +102,38 @@ bool swift_ASTGen_pluginServerLoadLibraryPlugin(
84102
void *_Nonnull handle, const char *_Nonnull libraryPath,
85103
const char *_Nonnull moduleName, BridgedStringRef *_Nullable errorOut);
86104

105+
/// Build a TypeRepr for AST node for the type at the given source location in
106+
/// the specified file.
107+
swift::TypeRepr *_Nullable swift_ASTGen_buildTypeRepr(
108+
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
109+
BridgedSourceLoc sourceLoc, BridgedDeclContext declContext,
110+
BridgedASTContext astContext, BridgedLegacyParser legacyParser,
111+
BridgedSourceLoc *_Nonnull endSourceLoc);
112+
113+
/// Build a Decl for AST node for the type at the given source location in the
114+
/// specified file.
115+
swift::Decl *_Nullable swift_ASTGen_buildDecl(
116+
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
117+
BridgedSourceLoc sourceLoc, BridgedDeclContext declContext,
118+
BridgedASTContext astContext, BridgedLegacyParser legacyParser,
119+
BridgedSourceLoc *_Nonnull endSourceLoc);
120+
121+
/// Build a Expr for AST node for the type at the given source location in the
122+
/// specified file.
123+
swift::Expr *_Nullable swift_ASTGen_buildExpr(
124+
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
125+
BridgedSourceLoc sourceLoc, BridgedDeclContext declContext,
126+
BridgedASTContext astContext, BridgedLegacyParser legacyParser,
127+
BridgedSourceLoc *_Nonnull endSourceLoc);
128+
129+
/// Build a Stmt for AST node for the type at the given source location in the
130+
/// specified file.
131+
swift::Stmt *_Nullable swift_ASTGen_buildStmt(
132+
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
133+
BridgedSourceLoc sourceLoc, BridgedDeclContext declContext,
134+
BridgedASTContext astContext, BridgedLegacyParser legacyParser,
135+
BridgedSourceLoc *_Nonnull endSourceLoc);
136+
87137
#ifdef __cplusplus
88138
}
89139
#endif

include/swift/Parse/ParseBridging.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===--- ParseBridging.h --------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_PARSE_PARSEBRIDGING_H
14+
#define SWIFT_PARSE_PARSEBRIDGING_H
15+
16+
#include "swift/AST/ASTBridging.h"
17+
#include "swift/Basic/BasicBridging.h"
18+
19+
#ifdef USED_IN_CPP_SOURC
20+
#include "swift/Parse/Parser.h"
21+
#else
22+
namespace swift {
23+
class Parser;
24+
}
25+
#endif
26+
27+
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
28+
29+
class BridgedLegacyParser {
30+
swift::Parser *_Nonnull const handle;
31+
32+
public:
33+
#ifdef USED_IN_CPP_SOURCE
34+
BridgedLegacyParser(swift::Parser &P) : handle(&P) {}
35+
36+
swift::Parser &unbridged() const { return *handle; }
37+
#endif
38+
};
39+
40+
SWIFT_NAME("BridgedLegacyParser.parseExpr(self:_:_:_:)")
41+
BridgedExpr BridgedLegacyParser_parseExpr(BridgedLegacyParser,
42+
BridgedSourceLoc loc,
43+
BridgedDeclContext DC,
44+
bool isExprBasic);
45+
46+
SWIFT_NAME("BridgedLegacyParser.parseDecl(self:_:_:)")
47+
BridgedDecl BridgedLegacyParser_parseDecl(BridgedLegacyParser,
48+
BridgedSourceLoc loc,
49+
BridgedDeclContext DC);
50+
51+
SWIFT_NAME("BridgedLegacyParser.parseStmt(self:_:_:)")
52+
BridgedStmt BridgedLegacyParser_parseStmt(BridgedLegacyParser,
53+
BridgedSourceLoc loc,
54+
BridgedDeclContext DC);
55+
56+
SWIFT_NAME("BridgedLegacyParser.parseType(self:_:_:)")
57+
BridgedTypeRepr BridgedLegacyParser_parseType(BridgedLegacyParser,
58+
BridgedSourceLoc loc,
59+
BridgedDeclContext DC);
60+
61+
SWIFT_END_NULLABILITY_ANNOTATIONS
62+
63+
#endif // SWIFT_PARSE_PARSEBRIDGING_H

include/swift/Parse/Parser.h

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,11 @@ class Parser {
158158
bool InSwiftKeyPath = false;
159159
bool InFreestandingMacroArgument = false;
160160

161+
#if SWIFT_BUILD_SWIFT_SYNTAX
162+
// This Parser is a fallback parser for ASTGen.
163+
bool IsForASTGen = false;
164+
#endif
165+
161166
// A cached answer to
162167
// Context.LangOpts.hasFeature(Feature::NoncopyableGenerics)
163168
// to ensure there's no parsing performance regression.
@@ -957,7 +962,8 @@ class Parser {
957962

958963
ParserResult<Decl> parseDecl(bool IsAtStartOfLineOrPreviousHadSemi,
959964
bool IfConfigsAreDeclAttrs,
960-
llvm::function_ref<void(Decl *)> Handler);
965+
llvm::function_ref<void(Decl *)> Handler,
966+
bool fromASTGen = false);
961967

962968
std::pair<std::vector<Decl *>, llvm::Optional<Fingerprint>>
963969
parseDeclListDelayed(IterableDeclContext *IDC);
@@ -1349,50 +1355,6 @@ class Parser {
13491355
/// Get the location for a type error.
13501356
SourceLoc getTypeErrorLoc() const;
13511357

1352-
/// Callback function used for creating a C++ AST from the syntax node at the given source location.
1353-
///
1354-
/// The arguments to this callback are the source file to pass into ASTGen (the exported source file)
1355-
/// and the source location pointer to pass into ASTGen (to find the syntax node).
1356-
///
1357-
/// The callback returns the new AST node and the ending location of the syntax node. If the AST node
1358-
/// is NULL, something went wrong.
1359-
template<typename T>
1360-
using ASTFromSyntaxTreeCallback = std::pair<T*, const void *>(
1361-
void *sourceFile, const void *sourceLoc
1362-
);
1363-
1364-
/// Parse by constructing a C++ AST node from the Swift syntax tree via ASTGen.
1365-
template<typename T>
1366-
ParserResult<T> parseASTFromSyntaxTree(
1367-
llvm::function_ref<ASTFromSyntaxTreeCallback<T>> body
1368-
) {
1369-
if (!Context.LangOpts.hasFeature(Feature::ASTGenTypes))
1370-
return nullptr;
1371-
1372-
auto exportedSourceFile = SF.getExportedSourceFile();
1373-
if (!exportedSourceFile)
1374-
return nullptr;
1375-
1376-
// Perform the translation.
1377-
auto sourceLoc = Tok.getLoc().getOpaquePointerValue();
1378-
T* astNode;
1379-
const void *endLocPtr;
1380-
std::tie(astNode, endLocPtr) = body(exportedSourceFile, sourceLoc);
1381-
1382-
if (!astNode) {
1383-
assert(false && "Could not build AST node from syntax tree");
1384-
return nullptr;
1385-
}
1386-
1387-
// Reset the lexer to the ending location.
1388-
StringRef contents =
1389-
SourceMgr.extractText(SourceMgr.getRangeForBuffer(L->getBufferID()));
1390-
L->resetToOffset((const char *)endLocPtr - contents.data());
1391-
L->lex(Tok);
1392-
1393-
return makeParserResult(astNode);
1394-
}
1395-
13961358
//===--------------------------------------------------------------------===//
13971359
// Type Parsing
13981360

@@ -1409,9 +1371,10 @@ class Parser {
14091371
ParseTypeReason reason);
14101372

14111373
ParserResult<TypeRepr> parseType();
1412-
ParserResult<TypeRepr> parseType(
1413-
Diag<> MessageID,
1414-
ParseTypeReason reason = ParseTypeReason::Unspecified);
1374+
ParserResult<TypeRepr>
1375+
parseType(Diag<> MessageID,
1376+
ParseTypeReason reason = ParseTypeReason::Unspecified,
1377+
bool fromASTGen = false);
14151378

14161379
/// Parse a type optionally prefixed by a list of named opaque parameters. If
14171380
/// no params present, return 'type'. Otherwise, return 'type-named-opaque'.
@@ -1735,7 +1698,8 @@ class Parser {
17351698
ParserResult<Expr> parseExprBasic(Diag<> ID) {
17361699
return parseExprImpl(ID, /*isExprBasic=*/true);
17371700
}
1738-
ParserResult<Expr> parseExprImpl(Diag<> ID, bool isExprBasic);
1701+
ParserResult<Expr> parseExprImpl(Diag<> ID, bool isExprBasic,
1702+
bool fromASTGen = false);
17391703
ParserResult<Expr> parseExprIs();
17401704
ParserResult<Expr> parseExprAs();
17411705
ParserResult<Expr> parseExprArrow();
@@ -1944,7 +1908,7 @@ class Parser {
19441908

19451909
bool isTerminatorForBraceItemListKind(BraceItemListKind Kind,
19461910
ArrayRef<ASTNode> ParsedDecls);
1947-
ParserResult<Stmt> parseStmt();
1911+
ParserResult<Stmt> parseStmt(bool fromASTGen = false);
19481912
ParserStatus parseExprOrStmt(ASTNode &Result);
19491913
ParserResult<Stmt> parseStmtBreak();
19501914
ParserResult<Stmt> parseStmtContinue();
@@ -2075,6 +2039,18 @@ class Parser {
20752039
bool parseLegacyTildeCopyable(SourceLoc *parseTildeCopyable,
20762040
ParserStatus &Status,
20772041
SourceLoc &TildeCopyableLoc);
2042+
2043+
//===--------------------------------------------------------------------===//
2044+
// ASTGen support.
2045+
2046+
/// Parse a TypeRepr from the syntax tree. i.e. SF->getExportedSourceFile()
2047+
ParserResult<TypeRepr> parseTypeReprFromSyntaxTree();
2048+
/// Parse a Stmt from the syntax tree. i.e. SF->getExportedSourceFile()
2049+
ParserResult<Stmt> parseStmtFromSyntaxTree();
2050+
/// Parse a Decl from the syntax tree. i.e. SF->getExportedSourceFile()
2051+
ParserResult<Decl> parseDeclFromSyntaxTree();
2052+
/// Parse an Expr from the syntax tree. i.e. SF->getExportedSourceFile()
2053+
ParserResult<Expr> parseExprFromSyntaxTree();
20782054
};
20792055

20802056
/// Describes a parsed declaration name.

lib/AST/ASTBridging.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,42 @@ BridgedParamDecl BridgedParamDecl_createParsed(
326326
auto *paramDecl = new (cContext.unbridged())
327327
ParamDecl(cSpecifierLoc.unbridged(), firstNameLoc, firstName,
328328
secondNameLoc, secondName, declContext);
329-
paramDecl->setTypeRepr(opaqueType.unbridged());
329+
330+
if (auto type = opaqueType.unbridged()) {
331+
paramDecl->setTypeRepr(type);
332+
333+
// FIXME: Copied from 'Parser::parsePattern()'. This should be in Sema.
334+
// Dig through the type to find any attributes or modifiers that are
335+
// associated with the type but should also be reflected on the
336+
// declaration.
337+
auto unwrappedType = type;
338+
while (true) {
339+
if (auto *ATR = dyn_cast<AttributedTypeRepr>(unwrappedType)) {
340+
auto &attrs = ATR->getAttrs();
341+
// At this point we actually don't know if that's valid to mark
342+
// this parameter declaration as `autoclosure` because type has
343+
// not been resolved yet - it should either be a function type
344+
// or typealias with underlying function type.
345+
paramDecl->setAutoClosure(attrs.has(TypeAttrKind::TAK_autoclosure));
346+
347+
unwrappedType = ATR->getTypeRepr();
348+
continue;
349+
}
350+
351+
if (auto *STR = dyn_cast<SpecifierTypeRepr>(unwrappedType)) {
352+
if (isa<IsolatedTypeRepr>(STR))
353+
paramDecl->setIsolated(true);
354+
else if (isa<CompileTimeConstTypeRepr>(STR))
355+
paramDecl->setCompileTimeConst(true);
356+
357+
unwrappedType = STR->getBase();
358+
continue;
359+
}
360+
361+
break;
362+
}
363+
}
364+
330365
paramDecl->setDefaultExpr(defaultValue, /*isTypeChecked*/ false);
331366
paramDecl->setDefaultArgumentKind(defaultArgumentKind);
332367

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,10 +3426,6 @@ static bool usesFeatureParserASTGen(Decl *decl) {
34263426
return false;
34273427
}
34283428

3429-
static bool usesFeatureASTGenTypes(Decl *decl) {
3430-
return false;
3431-
}
3432-
34333429
static bool usesFeatureBuiltinMacros(Decl *decl) {
34343430
return false;
34353431
}

lib/ASTGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_pure_swift_host_library(swiftASTGen STATIC
1313
Sources/ASTGen/DiagnosticsBridge.swift
1414
Sources/ASTGen/Exprs.swift
1515
Sources/ASTGen/Generics.swift
16+
Sources/ASTGen/LegacyParse.swift
1617
Sources/ASTGen/Literals.swift
1718
Sources/ASTGen/Macros.swift
1819
Sources/ASTGen/ParameterClause.swift

0 commit comments

Comments
 (0)