Skip to content

Commit e566a74

Browse files
committed
[ASTGen] Support macro expanded buffer
* Make ExportedSourceFile hold any Syntax as the root node * Move `ExportedSourceFileRequest::evaluate()` to `ParseRequests.cpp` * Pass the decl context and `GeneatedSourceFileInfo::Kind` to `swift_ASTGen_parseSourceFile()` to customize the parsing * Make `ExportedSourceFile` to hold an arbitrary Syntax node * Move round-trip checking into `ExportedSourceFileRequest::evaluate()` * Split `parseSourceFileViaASTGen` completely from C++ parsing logic (in `ParseSourceFileRequest::evaluate()`) * Remove 'ParserDiagnostics' experimental feature: Now that we have ParserASTGen mode which includes the swift-syntax parser diagnostics.
1 parent 919ec93 commit e566a74

21 files changed

+408
-297
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,19 @@ void BridgedDiagnostic_finish(BridgedDiagnostic cDiag);
504504
//===----------------------------------------------------------------------===//
505505

506506
SWIFT_NAME("getter:BridgedDeclContext.isLocalContext(self:)")
507-
bool BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext);
507+
BRIDGED_INLINE bool
508+
BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext);
509+
510+
SWIFT_NAME("getter:BridgedDeclContext.isTypeContext(self:)")
511+
BRIDGED_INLINE bool BridgedDeclContext_isTypeContext(BridgedDeclContext dc);
512+
513+
SWIFT_NAME("getter:BridgedDeclContext.isModuleScopeContext(self:)")
514+
BRIDGED_INLINE bool
515+
BridgedDeclContext_isModuleScopeContext(BridgedDeclContext dc);
516+
517+
SWIFT_NAME("getter:BridgedDeclContext.astContext(self:)")
518+
BRIDGED_INLINE BridgedASTContext
519+
BridgedDeclContext_getASTContext(BridgedDeclContext dc);
508520

509521
SWIFT_NAME("BridgedPatternBindingInitializer.create(declContext:)")
510522
BridgedPatternBindingInitializer
@@ -1365,6 +1377,12 @@ BridgedPackExpansionExpr_createParsed(BridgedASTContext cContext,
13651377
BridgedSourceLoc cRepeatLoc,
13661378
BridgedExpr cPatternExpr);
13671379

1380+
SWIFT_NAME("BridgedParenExpr.createParsed(_:leftParenLoc:expr:rightParenLoc:)")
1381+
BridgedParenExpr BridgedParenExpr_createParsed(BridgedASTContext cContext,
1382+
BridgedSourceLoc cLParen,
1383+
BridgedExpr cExpr,
1384+
BridgedSourceLoc cRParen);
1385+
13681386
SWIFT_NAME("BridgedPostfixUnaryExpr.createParsed(_:operator:operand:)")
13691387
BridgedPostfixUnaryExpr
13701388
BridgedPostfixUnaryExpr_createParsed(BridgedASTContext cContext,

include/swift/AST/ASTBridgingImpl.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818
#include "swift/AST/Decl.h"
1919
#include "swift/AST/Expr.h"
2020
#include "swift/AST/IfConfigClauseRangeInfo.h"
21-
#include "swift/AST/Stmt.h"
2221
#include "swift/AST/ProtocolConformance.h"
2322
#include "swift/AST/ProtocolConformanceRef.h"
23+
#include "swift/AST/SourceFile.h"
24+
#include "swift/AST/Stmt.h"
2425
#include "swift/Basic/Assertions.h"
2526

2627
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
@@ -97,6 +98,26 @@ BridgedStringRef BridgedASTContext_allocateCopyString(BridgedASTContext bridged,
9798
return bridged.unbridged().AllocateCopy(cStr.unbridged());
9899
}
99100

101+
//===----------------------------------------------------------------------===//
102+
// MARK: BridgedDeclContext
103+
//===----------------------------------------------------------------------===//
104+
105+
bool BridgedDeclContext_isLocalContext(BridgedDeclContext dc) {
106+
return dc.unbridged()->isLocalContext();
107+
}
108+
109+
bool BridgedDeclContext_isTypeContext(BridgedDeclContext dc) {
110+
return dc.unbridged()->isTypeContext();
111+
}
112+
113+
bool BridgedDeclContext_isModuleScopeContext(BridgedDeclContext dc) {
114+
return dc.unbridged()->isModuleScopeContext();
115+
}
116+
117+
BridgedASTContext BridgedDeclContext_getASTContext(BridgedDeclContext dc) {
118+
return dc.unbridged()->getASTContext();
119+
}
120+
100121
//===----------------------------------------------------------------------===//
101122
// MARK: BridgedDeclObj
102123
//===----------------------------------------------------------------------===//

include/swift/AST/SourceFile.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,8 @@ class SourceFile final : public FileUnit {
595595
return BufferID;
596596
}
597597

598+
const GeneratedSourceInfo *getGeneratedSourceFileInfo() const;
599+
598600
/// For source files created to hold the source code created by expanding
599601
/// a macro, this is the AST node that describes the macro expansion.
600602
///
@@ -641,6 +643,9 @@ class SourceFile final : public FileUnit {
641643
/// Otherwise, return an empty string.
642644
StringRef getFilename() const;
643645

646+
/// Retrieve the source text buffer.
647+
StringRef getBuffer() const;
648+
644649
/// Retrieve the scope that describes this source file.
645650
ASTScope &getScope();
646651

include/swift/Basic/BasicBridging.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,23 @@ class BridgedSwiftVersion {
432432
unsigned getMinor() const { return Minor; }
433433
};
434434

435+
//===----------------------------------------------------------------------===//
436+
// MARK: GeneratedSourceInfo
437+
//===----------------------------------------------------------------------===//
438+
439+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGeneratedSourceFileKind {
440+
#define MACRO_ROLE(Name, Description) \
441+
BridgedGeneratedSourceFileKind##Name##MacroExpansion,
442+
#include "swift/Basic/MacroRoles.def"
443+
#undef MACRO_ROLE
444+
445+
BridgedGeneratedSourceFileKindReplacedFunctionBody,
446+
BridgedGeneratedSourceFileKindPrettyPrinted,
447+
BridgedGeneratedSourceFileKindDefaultArgument,
448+
449+
BridgedGeneratedSourceFileKindNone,
450+
};
451+
435452
SWIFT_END_NULLABILITY_ANNOTATIONS
436453

437454
#ifndef PURE_BRIDGING_MODE

include/swift/Basic/Features.def

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,11 +299,6 @@ EXPERIMENTAL_FEATURE(ParserRoundTrip, false)
299299
/// Swift parser.
300300
EXPERIMENTAL_FEATURE(ParserValidation, false)
301301

302-
/// Whether to emit diagnostics from the new parser first, and only emit
303-
/// diagnostics from the existing parser when there are none from the new
304-
/// parser.
305-
EXPERIMENTAL_FEATURE(ParserDiagnostics, false)
306-
307302
/// Enables implicit some while also enabling existential `any`
308303
EXPERIMENTAL_FEATURE(ImplicitSome, false)
309304

include/swift/Bridging/ASTGen.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ void swift_ASTGen_renderQueuedDiagnostics(
3737

3838
// FIXME: Hack because we cannot easily get to the already-parsed source
3939
// file from here. Fix this egregious oversight!
40-
void *_Nullable swift_ASTGen_parseSourceFile(const char *_Nonnull buffer,
41-
size_t bufferLength,
42-
const char *_Nonnull moduleName,
43-
const char *_Nonnull filename,
44-
void *_Nullable ctx);
40+
void *_Nullable swift_ASTGen_parseSourceFile(BridgedStringRef buffer,
41+
BridgedStringRef moduleName,
42+
BridgedStringRef filename,
43+
void *_Nullable declContextPtr,
44+
BridgedGeneratedSourceFileKind);
4545
void swift_ASTGen_destroySourceFile(void *_Nonnull sourceFile);
4646

4747
/// Check whether the given source file round-trips correctly. Returns 0 if
@@ -60,7 +60,7 @@ void swift_ASTGen_buildTopLevelASTNodes(
6060
BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile,
6161
BridgedDeclContext declContext, BridgedASTContext astContext,
6262
BridgedLegacyParser legacyParser, void *_Nonnull outputContext,
63-
void (*_Nonnull)(void *_Nonnull, void *_Nonnull));
63+
void (*_Nonnull)(BridgedASTNode, void *_Nonnull));
6464

6565
void swift_ASTGen_freeBridgedString(BridgedStringRef);
6666

include/swift/Parse/Parser.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -930,12 +930,6 @@ class Parser {
930930
/// Each item will be a declaration, statement, or expression.
931931
void parseTopLevelItems(SmallVectorImpl<ASTNode> &items);
932932

933-
/// Parse the source file via the Swift Parser using the ASTGen library.
934-
void
935-
parseSourceFileViaASTGen(SmallVectorImpl<ASTNode> &items,
936-
std::optional<DiagnosticTransaction> &transaction,
937-
bool suppressDiagnostics = false);
938-
939933
/// Parse the top-level SIL decls into the SIL module.
940934
/// \returns \c true if there was a parsing error.
941935
bool parseTopLevelSIL();

lib/AST/Bridging/DeclContextBridging.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ using namespace swift;
2020
// MARK: DeclContexts
2121
//===----------------------------------------------------------------------===//
2222

23-
bool BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext) {
24-
return cDeclContext.unbridged()->isLocalContext();
25-
}
26-
2723
BridgedPatternBindingInitializer
2824
BridgedPatternBindingInitializer_create(BridgedDeclContext cDeclContext) {
2925
return PatternBindingInitializer::create(cDeclContext.unbridged());

lib/AST/Bridging/ExprBridging.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,14 @@ BridgedRegexLiteralExpr_createParsed(BridgedASTContext cContext,
383383
cRegexText.unbridged());
384384
}
385385

386+
BridgedParenExpr BridgedParenExpr_createParsed(BridgedASTContext cContext,
387+
BridgedSourceLoc cLParen,
388+
BridgedExpr cExpr,
389+
BridgedSourceLoc cRParen) {
390+
ASTContext &context = cContext.unbridged();
391+
return new (context)
392+
ParenExpr(cLParen.unbridged(), cExpr.unbridged(), cRParen.unbridged());
393+
}
386394
BridgedSequenceExpr BridgedSequenceExpr_createParsed(BridgedASTContext cContext,
387395
BridgedArrayRef exprs) {
388396
return SequenceExpr::create(cContext.unbridged(), exprs.unbridged<Expr *>());

lib/AST/DiagnosticBridge.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ void *DiagnosticBridge::getSourceFileSyntax(SourceManager &sourceMgr,
114114

115115
auto bufferContents = sourceMgr.getEntireTextForBuffer(bufferID);
116116
auto sourceFile = swift_ASTGen_parseSourceFile(
117-
bufferContents.data(), bufferContents.size(), "module",
118-
displayName.str().c_str(), /*ctx*/ nullptr);
117+
bufferContents, StringRef{"module"}, displayName,
118+
/*declContextPtr=*/nullptr, BridgedGeneratedSourceFileKindNone);
119119

120120
sourceFileSyntax[{&sourceMgr, bufferID}] = sourceFile;
121121
return sourceFile;

lib/AST/Module.cpp

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,10 @@ void SourceFile::lookupClassMembers(ImportPath::Access accessPath,
10731073
cache.lookupClassMembers(accessPath, consumer);
10741074
}
10751075

1076+
const GeneratedSourceInfo *SourceFile::getGeneratedSourceFileInfo() const {
1077+
return getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1078+
}
1079+
10761080
ASTNode SourceFile::getMacroExpansion() const {
10771081
if (Kind != SourceFileKind::MacroExpansion)
10781082
return nullptr;
@@ -1084,28 +1088,22 @@ SourceRange SourceFile::getMacroInsertionRange() const {
10841088
if (Kind != SourceFileKind::MacroExpansion)
10851089
return SourceRange();
10861090

1087-
auto generatedInfo =
1088-
*getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1089-
auto origRange = generatedInfo.originalSourceRange;
1091+
auto origRange = getGeneratedSourceFileInfo()->originalSourceRange;
10901092
return {origRange.getStart(), origRange.getEnd()};
10911093
}
10921094

10931095
CustomAttr *SourceFile::getAttachedMacroAttribute() const {
10941096
if (Kind != SourceFileKind::MacroExpansion)
10951097
return nullptr;
10961098

1097-
auto genInfo =
1098-
*getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1099-
return genInfo.attachedMacroCustomAttr;
1099+
return getGeneratedSourceFileInfo()->attachedMacroCustomAttr;
11001100
}
11011101

11021102
std::optional<MacroRole> SourceFile::getFulfilledMacroRole() const {
11031103
if (Kind != SourceFileKind::MacroExpansion)
11041104
return std::nullopt;
11051105

1106-
auto genInfo =
1107-
*getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1108-
switch (genInfo.kind) {
1106+
switch (getGeneratedSourceFileInfo()->kind) {
11091107
#define MACRO_ROLE(Name, Description) \
11101108
case GeneratedSourceInfo::Name##MacroExpansion: \
11111109
return MacroRole::Name;
@@ -1123,9 +1121,7 @@ SourceFile *SourceFile::getEnclosingSourceFile() const {
11231121
Kind != SourceFileKind::DefaultArgument)
11241122
return nullptr;
11251123

1126-
auto genInfo =
1127-
*getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1128-
auto sourceLoc = genInfo.originalSourceRange.getStart();
1124+
auto sourceLoc = getGeneratedSourceFileInfo()->originalSourceRange.getStart();
11291125
return getParentModule()->getSourceFileContainingLocation(sourceLoc);
11301126
}
11311127

@@ -1134,9 +1130,7 @@ ASTNode SourceFile::getNodeInEnclosingSourceFile() const {
11341130
Kind != SourceFileKind::DefaultArgument)
11351131
return nullptr;
11361132

1137-
auto genInfo =
1138-
*getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID());
1139-
return ASTNode::getFromOpaqueValue(genInfo.astNode);
1133+
return ASTNode::getFromOpaqueValue(getGeneratedSourceFileInfo()->astNode);
11401134
}
11411135

11421136
void ModuleDecl::lookupClassMember(ImportPath::Access accessPath,
@@ -3573,6 +3567,11 @@ StringRef SourceFile::getFilename() const {
35733567
return SM.getIdentifierForBuffer(BufferID);
35743568
}
35753569

3570+
StringRef SourceFile::getBuffer() const {
3571+
SourceManager &SM = getASTContext().SourceMgr;
3572+
return SM.getEntireTextForBuffer(BufferID);
3573+
}
3574+
35763575
ASTScope &SourceFile::getScope() {
35773576
if (!Scope)
35783577
Scope = new (getASTContext()) ASTScope(this);

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -101,52 +101,59 @@ struct ASTGenVisitor {
101101
self.legacyParse = legacyParser
102102
}
103103

104-
func generate(sourceFile node: SourceFileSyntax) -> [BridgedDecl] {
105-
var out = [BridgedDecl]()
104+
func generate(sourceFile node: SourceFileSyntax) -> [ASTNode] {
105+
var out = [ASTNode]()
106+
let isTopLevel = self.declContext.isModuleScopeContext
106107

107108
visitIfConfigElements(
108109
node.statements,
109110
of: CodeBlockItemSyntax.self,
110111
split: Self.splitCodeBlockItemIfConfig
111112
) { element in
112-
let loc = self.generateSourceLoc(element)
113+
let astNode = generate(codeBlockItem: element)
114+
if !isTopLevel {
115+
out.append(astNode)
116+
return
117+
}
113118

114-
func endLoc() -> BridgedSourceLoc {
119+
func getRange() -> (start: BridgedSourceLoc, end: BridgedSourceLoc) {
120+
let loc = self.generateSourceLoc(element)
115121
if let endTok = element.lastToken(viewMode: .sourceAccurate) {
116122
switch endTok.parent?.kind {
117123
case .stringLiteralExpr, .regexLiteralExpr:
118124
// string/regex literal are single token in AST.
119-
return self.generateSourceLoc(endTok.parent)
125+
return (loc, self.generateSourceLoc(endTok.parent))
120126
default:
121-
return self.generateSourceLoc(endTok)
127+
return (loc, self.generateSourceLoc(endTok))
122128
}
123129
} else {
124-
return loc
130+
return (loc, loc)
125131
}
126132
}
127133

128-
let swiftASTNodes = generate(codeBlockItem: element)
129-
switch swiftASTNodes {
134+
switch astNode {
130135
case .decl(let d):
131-
out.append(d)
136+
out.append(.decl(d))
132137
case .stmt(let s):
138+
let range = getRange()
133139
let topLevelDecl = BridgedTopLevelCodeDecl.createParsed(
134140
self.ctx,
135141
declContext: self.declContext,
136-
startLoc: loc,
142+
startLoc: range.start,
137143
stmt: s,
138-
endLoc: endLoc()
144+
endLoc: range.end
139145
)
140-
out.append(topLevelDecl.asDecl)
146+
out.append(.decl(topLevelDecl.asDecl))
141147
case .expr(let e):
148+
let range = getRange()
142149
let topLevelDecl = BridgedTopLevelCodeDecl.createParsed(
143150
self.ctx,
144151
declContext: self.declContext,
145-
startLoc: loc,
152+
startLoc: range.start,
146153
expr: e,
147-
endLoc: endLoc()
154+
endLoc: range.end
148155
)
149-
out.append(topLevelDecl.asDecl)
156+
out.append(.decl(topLevelDecl.asDecl))
150157
}
151158
}
152159

@@ -442,7 +449,7 @@ public func buildTopLevelASTNodes(
442449
ctx: BridgedASTContext,
443450
legacyParser: BridgedLegacyParser,
444451
outputContext: UnsafeMutableRawPointer,
445-
callback: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void
452+
callback: @convention(c) (BridgedASTNode, UnsafeMutableRawPointer) -> Void
446453
) {
447454
let sourceFile = sourceFilePtr.assumingMemoryBound(to: ExportedSourceFile.self)
448455
let visitor = ASTGenVisitor(
@@ -454,8 +461,18 @@ public func buildTopLevelASTNodes(
454461
legacyParser: legacyParser
455462
)
456463

457-
visitor.generate(sourceFile: sourceFile.pointee.syntax)
458-
.forEach { callback($0.raw, outputContext) }
464+
switch sourceFile.pointee.syntax.as(SyntaxEnum.self) {
465+
case .sourceFile(let node):
466+
for elem in visitor.generate(sourceFile: node) {
467+
callback(elem.bridged, outputContext)
468+
}
469+
case .memberBlockItemList(let node):
470+
for elem in visitor.generate(memberBlockItemList: node) {
471+
callback(ASTNode.decl(elem).bridged, outputContext)
472+
}
473+
default:
474+
fatalError("invalid syntax for a source file")
475+
}
459476

460477
// Diagnose any errors from evaluating #ifs.
461478
visitor.diagnoseAll(visitor.configuredRegions.diagnostics)

0 commit comments

Comments
 (0)