Skip to content

Commit fb08a92

Browse files
committed
[ASTGen] Infrastructure to implment ASTGen Incrementally
* 'ASTGenVisitor' has a reference to a legacy C++ Parser configured for ASTGen. * If 'ASTGenVisitor' encounters a AST node that hasn't been migrated, call parse(Decl|Stmt|Expr|Type) to parse the position using the legacy parser. * The legacy parser calls ASTGen's 'swift_ASTGen_build(Decl|Stmt|Expr|Type)' for each ASTNode "parsing" (unless the call is not directly from the ASTGen.) rdar://117151886
1 parent 2c8d7f2 commit fb08a92

18 files changed

+811
-203
lines changed

include/module.modulemap

+6
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

+2
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/Bridging/ASTGen.h

+50
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

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
BridgedASTContext getASTContext() const;
40+
BridgedDiagnosticEngine getDiagnosticEngine() const;
41+
BridgedStringRef getSourceBuffer() const;
42+
BridgedDeclContext getCurrDeclContext() const;
43+
44+
BridgedExpr parseExpr(BridgedSourceLoc loc, BridgedDeclContext DC,
45+
bool isExprBasic) const;
46+
BridgedDecl parseDecl(BridgedSourceLoc loc, BridgedDeclContext DC) const;
47+
BridgedStmt parseStmt(BridgedSourceLoc loc, BridgedDeclContext DC) const;
48+
BridgedTypeRepr parseType(BridgedSourceLoc loc, BridgedDeclContext DC) const;
49+
};
50+
51+
SWIFT_END_NULLABILITY_ANNOTATIONS
52+
53+
#endif // SWIFT_PARSE_PARSEBRIDGING_H

include/swift/Parse/Parser.h

+26-50
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/ASTGen/CMakeLists.txt

+1
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)