diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index b4b013b588c6e..4c093b3bafb3e 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -504,7 +504,19 @@ void BridgedDiagnostic_finish(BridgedDiagnostic cDiag); //===----------------------------------------------------------------------===// SWIFT_NAME("getter:BridgedDeclContext.isLocalContext(self:)") -bool BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext); +BRIDGED_INLINE bool +BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext); + +SWIFT_NAME("getter:BridgedDeclContext.isTypeContext(self:)") +BRIDGED_INLINE bool BridgedDeclContext_isTypeContext(BridgedDeclContext dc); + +SWIFT_NAME("getter:BridgedDeclContext.isModuleScopeContext(self:)") +BRIDGED_INLINE bool +BridgedDeclContext_isModuleScopeContext(BridgedDeclContext dc); + +SWIFT_NAME("getter:BridgedDeclContext.astContext(self:)") +BRIDGED_INLINE BridgedASTContext +BridgedDeclContext_getASTContext(BridgedDeclContext dc); SWIFT_NAME("BridgedPatternBindingInitializer.create(declContext:)") BridgedPatternBindingInitializer @@ -1365,6 +1377,12 @@ BridgedPackExpansionExpr_createParsed(BridgedASTContext cContext, BridgedSourceLoc cRepeatLoc, BridgedExpr cPatternExpr); +SWIFT_NAME("BridgedParenExpr.createParsed(_:leftParenLoc:expr:rightParenLoc:)") +BridgedParenExpr BridgedParenExpr_createParsed(BridgedASTContext cContext, + BridgedSourceLoc cLParen, + BridgedExpr cExpr, + BridgedSourceLoc cRParen); + SWIFT_NAME("BridgedPostfixUnaryExpr.createParsed(_:operator:operand:)") BridgedPostfixUnaryExpr BridgedPostfixUnaryExpr_createParsed(BridgedASTContext cContext, diff --git a/include/swift/AST/ASTBridgingImpl.h b/include/swift/AST/ASTBridgingImpl.h index eb222aa3760ce..0ae2f38368d4f 100644 --- a/include/swift/AST/ASTBridgingImpl.h +++ b/include/swift/AST/ASTBridgingImpl.h @@ -18,9 +18,10 @@ #include "swift/AST/Decl.h" #include "swift/AST/Expr.h" #include "swift/AST/IfConfigClauseRangeInfo.h" -#include "swift/AST/Stmt.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/ProtocolConformanceRef.h" +#include "swift/AST/SourceFile.h" +#include "swift/AST/Stmt.h" #include "swift/Basic/Assertions.h" SWIFT_BEGIN_NULLABILITY_ANNOTATIONS @@ -97,6 +98,26 @@ BridgedStringRef BridgedASTContext_allocateCopyString(BridgedASTContext bridged, return bridged.unbridged().AllocateCopy(cStr.unbridged()); } +//===----------------------------------------------------------------------===// +// MARK: BridgedDeclContext +//===----------------------------------------------------------------------===// + +bool BridgedDeclContext_isLocalContext(BridgedDeclContext dc) { + return dc.unbridged()->isLocalContext(); +} + +bool BridgedDeclContext_isTypeContext(BridgedDeclContext dc) { + return dc.unbridged()->isTypeContext(); +} + +bool BridgedDeclContext_isModuleScopeContext(BridgedDeclContext dc) { + return dc.unbridged()->isModuleScopeContext(); +} + +BridgedASTContext BridgedDeclContext_getASTContext(BridgedDeclContext dc) { + return dc.unbridged()->getASTContext(); +} + //===----------------------------------------------------------------------===// // MARK: BridgedDeclObj //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index a5ee37528c783..fc4b76f44544e 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -595,6 +595,8 @@ class SourceFile final : public FileUnit { return BufferID; } + const GeneratedSourceInfo *getGeneratedSourceFileInfo() const; + /// For source files created to hold the source code created by expanding /// a macro, this is the AST node that describes the macro expansion. /// @@ -641,6 +643,9 @@ class SourceFile final : public FileUnit { /// Otherwise, return an empty string. StringRef getFilename() const; + /// Retrieve the source text buffer. + StringRef getBuffer() const; + /// Retrieve the scope that describes this source file. ASTScope &getScope(); diff --git a/include/swift/Basic/BasicBridging.h b/include/swift/Basic/BasicBridging.h index 3c0da9bf4cc80..5aa3a9faed9f3 100644 --- a/include/swift/Basic/BasicBridging.h +++ b/include/swift/Basic/BasicBridging.h @@ -432,6 +432,23 @@ class BridgedSwiftVersion { unsigned getMinor() const { return Minor; } }; +//===----------------------------------------------------------------------===// +// MARK: GeneratedSourceInfo +//===----------------------------------------------------------------------===// + +enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedGeneratedSourceFileKind { +#define MACRO_ROLE(Name, Description) \ + BridgedGeneratedSourceFileKind##Name##MacroExpansion, +#include "swift/Basic/MacroRoles.def" +#undef MACRO_ROLE + + BridgedGeneratedSourceFileKindReplacedFunctionBody, + BridgedGeneratedSourceFileKindPrettyPrinted, + BridgedGeneratedSourceFileKindDefaultArgument, + + BridgedGeneratedSourceFileKindNone, +}; + SWIFT_END_NULLABILITY_ANNOTATIONS #ifndef PURE_BRIDGING_MODE diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index 2932c3cb61b26..8cee21701032a 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -299,11 +299,6 @@ EXPERIMENTAL_FEATURE(ParserRoundTrip, false) /// Swift parser. EXPERIMENTAL_FEATURE(ParserValidation, false) -/// Whether to emit diagnostics from the new parser first, and only emit -/// diagnostics from the existing parser when there are none from the new -/// parser. -EXPERIMENTAL_FEATURE(ParserDiagnostics, false) - /// Enables implicit some while also enabling existential `any` EXPERIMENTAL_FEATURE(ImplicitSome, false) diff --git a/include/swift/Bridging/ASTGen.h b/include/swift/Bridging/ASTGen.h index 20ace660c2e22..a3b51f91cd73d 100644 --- a/include/swift/Bridging/ASTGen.h +++ b/include/swift/Bridging/ASTGen.h @@ -37,11 +37,11 @@ void swift_ASTGen_renderQueuedDiagnostics( // FIXME: Hack because we cannot easily get to the already-parsed source // file from here. Fix this egregious oversight! -void *_Nullable swift_ASTGen_parseSourceFile(const char *_Nonnull buffer, - size_t bufferLength, - const char *_Nonnull moduleName, - const char *_Nonnull filename, - void *_Nullable ctx); +void *_Nullable swift_ASTGen_parseSourceFile(BridgedStringRef buffer, + BridgedStringRef moduleName, + BridgedStringRef filename, + void *_Nullable declContextPtr, + BridgedGeneratedSourceFileKind); void swift_ASTGen_destroySourceFile(void *_Nonnull sourceFile); /// Check whether the given source file round-trips correctly. Returns 0 if @@ -60,7 +60,7 @@ void swift_ASTGen_buildTopLevelASTNodes( BridgedDiagnosticEngine diagEngine, void *_Nonnull sourceFile, BridgedDeclContext declContext, BridgedASTContext astContext, BridgedLegacyParser legacyParser, void *_Nonnull outputContext, - void (*_Nonnull)(void *_Nonnull, void *_Nonnull)); + void (*_Nonnull)(BridgedASTNode, void *_Nonnull)); void swift_ASTGen_freeBridgedString(BridgedStringRef); diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index bfd810a860a39..c94dbde85b4ba 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -930,12 +930,6 @@ class Parser { /// Each item will be a declaration, statement, or expression. void parseTopLevelItems(SmallVectorImpl &items); - /// Parse the source file via the Swift Parser using the ASTGen library. - void - parseSourceFileViaASTGen(SmallVectorImpl &items, - std::optional &transaction, - bool suppressDiagnostics = false); - /// Parse the top-level SIL decls into the SIL module. /// \returns \c true if there was a parsing error. bool parseTopLevelSIL(); diff --git a/lib/AST/Bridging/DeclContextBridging.cpp b/lib/AST/Bridging/DeclContextBridging.cpp index e11e1939a9422..b03deff0b8a61 100644 --- a/lib/AST/Bridging/DeclContextBridging.cpp +++ b/lib/AST/Bridging/DeclContextBridging.cpp @@ -20,10 +20,6 @@ using namespace swift; // MARK: DeclContexts //===----------------------------------------------------------------------===// -bool BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext) { - return cDeclContext.unbridged()->isLocalContext(); -} - BridgedPatternBindingInitializer BridgedPatternBindingInitializer_create(BridgedDeclContext cDeclContext) { return PatternBindingInitializer::create(cDeclContext.unbridged()); diff --git a/lib/AST/Bridging/ExprBridging.cpp b/lib/AST/Bridging/ExprBridging.cpp index b0a7a3583cb13..04eeed5ba409f 100644 --- a/lib/AST/Bridging/ExprBridging.cpp +++ b/lib/AST/Bridging/ExprBridging.cpp @@ -383,6 +383,14 @@ BridgedRegexLiteralExpr_createParsed(BridgedASTContext cContext, cRegexText.unbridged()); } +BridgedParenExpr BridgedParenExpr_createParsed(BridgedASTContext cContext, + BridgedSourceLoc cLParen, + BridgedExpr cExpr, + BridgedSourceLoc cRParen) { + ASTContext &context = cContext.unbridged(); + return new (context) + ParenExpr(cLParen.unbridged(), cExpr.unbridged(), cRParen.unbridged()); +} BridgedSequenceExpr BridgedSequenceExpr_createParsed(BridgedASTContext cContext, BridgedArrayRef exprs) { return SequenceExpr::create(cContext.unbridged(), exprs.unbridged()); diff --git a/lib/AST/DiagnosticBridge.cpp b/lib/AST/DiagnosticBridge.cpp index 13a62d45d0061..58b6234fd3b40 100644 --- a/lib/AST/DiagnosticBridge.cpp +++ b/lib/AST/DiagnosticBridge.cpp @@ -114,8 +114,8 @@ void *DiagnosticBridge::getSourceFileSyntax(SourceManager &sourceMgr, auto bufferContents = sourceMgr.getEntireTextForBuffer(bufferID); auto sourceFile = swift_ASTGen_parseSourceFile( - bufferContents.data(), bufferContents.size(), "module", - displayName.str().c_str(), /*ctx*/ nullptr); + bufferContents, StringRef{"module"}, displayName, + /*declContextPtr=*/nullptr, BridgedGeneratedSourceFileKindNone); sourceFileSyntax[{&sourceMgr, bufferID}] = sourceFile; return sourceFile; diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 9f5d9572aaf78..9179cde9c49e2 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -1073,6 +1073,10 @@ void SourceFile::lookupClassMembers(ImportPath::Access accessPath, cache.lookupClassMembers(accessPath, consumer); } +const GeneratedSourceInfo *SourceFile::getGeneratedSourceFileInfo() const { + return getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); +} + ASTNode SourceFile::getMacroExpansion() const { if (Kind != SourceFileKind::MacroExpansion) return nullptr; @@ -1084,9 +1088,7 @@ SourceRange SourceFile::getMacroInsertionRange() const { if (Kind != SourceFileKind::MacroExpansion) return SourceRange(); - auto generatedInfo = - *getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); - auto origRange = generatedInfo.originalSourceRange; + auto origRange = getGeneratedSourceFileInfo()->originalSourceRange; return {origRange.getStart(), origRange.getEnd()}; } @@ -1094,18 +1096,14 @@ CustomAttr *SourceFile::getAttachedMacroAttribute() const { if (Kind != SourceFileKind::MacroExpansion) return nullptr; - auto genInfo = - *getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); - return genInfo.attachedMacroCustomAttr; + return getGeneratedSourceFileInfo()->attachedMacroCustomAttr; } std::optional SourceFile::getFulfilledMacroRole() const { if (Kind != SourceFileKind::MacroExpansion) return std::nullopt; - auto genInfo = - *getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); - switch (genInfo.kind) { + switch (getGeneratedSourceFileInfo()->kind) { #define MACRO_ROLE(Name, Description) \ case GeneratedSourceInfo::Name##MacroExpansion: \ return MacroRole::Name; @@ -1123,9 +1121,7 @@ SourceFile *SourceFile::getEnclosingSourceFile() const { Kind != SourceFileKind::DefaultArgument) return nullptr; - auto genInfo = - *getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); - auto sourceLoc = genInfo.originalSourceRange.getStart(); + auto sourceLoc = getGeneratedSourceFileInfo()->originalSourceRange.getStart(); return getParentModule()->getSourceFileContainingLocation(sourceLoc); } @@ -1134,9 +1130,7 @@ ASTNode SourceFile::getNodeInEnclosingSourceFile() const { Kind != SourceFileKind::DefaultArgument) return nullptr; - auto genInfo = - *getASTContext().SourceMgr.getGeneratedSourceInfo(getBufferID()); - return ASTNode::getFromOpaqueValue(genInfo.astNode); + return ASTNode::getFromOpaqueValue(getGeneratedSourceFileInfo()->astNode); } void ModuleDecl::lookupClassMember(ImportPath::Access accessPath, @@ -3573,6 +3567,11 @@ StringRef SourceFile::getFilename() const { return SM.getIdentifierForBuffer(BufferID); } +StringRef SourceFile::getBuffer() const { + SourceManager &SM = getASTContext().SourceMgr; + return SM.getEntireTextForBuffer(BufferID); +} + ASTScope &SourceFile::getScope() { if (!Scope) Scope = new (getASTContext()) ASTScope(this); diff --git a/lib/ASTGen/Sources/ASTGen/ASTGen.swift b/lib/ASTGen/Sources/ASTGen/ASTGen.swift index 208b7313a20ec..5a3714e6d82a5 100644 --- a/lib/ASTGen/Sources/ASTGen/ASTGen.swift +++ b/lib/ASTGen/Sources/ASTGen/ASTGen.swift @@ -101,52 +101,59 @@ struct ASTGenVisitor { self.legacyParse = legacyParser } - func generate(sourceFile node: SourceFileSyntax) -> [BridgedDecl] { - var out = [BridgedDecl]() + func generate(sourceFile node: SourceFileSyntax) -> [ASTNode] { + var out = [ASTNode]() + let isTopLevel = self.declContext.isModuleScopeContext visitIfConfigElements( node.statements, of: CodeBlockItemSyntax.self, split: Self.splitCodeBlockItemIfConfig ) { element in - let loc = self.generateSourceLoc(element) + let astNode = generate(codeBlockItem: element) + if !isTopLevel { + out.append(astNode) + return + } - func endLoc() -> BridgedSourceLoc { + func getRange() -> (start: BridgedSourceLoc, end: BridgedSourceLoc) { + let loc = self.generateSourceLoc(element) if let endTok = element.lastToken(viewMode: .sourceAccurate) { switch endTok.parent?.kind { case .stringLiteralExpr, .regexLiteralExpr: // string/regex literal are single token in AST. - return self.generateSourceLoc(endTok.parent) + return (loc, self.generateSourceLoc(endTok.parent)) default: - return self.generateSourceLoc(endTok) + return (loc, self.generateSourceLoc(endTok)) } } else { - return loc + return (loc, loc) } } - let swiftASTNodes = generate(codeBlockItem: element) - switch swiftASTNodes { + switch astNode { case .decl(let d): - out.append(d) + out.append(.decl(d)) case .stmt(let s): + let range = getRange() let topLevelDecl = BridgedTopLevelCodeDecl.createParsed( self.ctx, declContext: self.declContext, - startLoc: loc, + startLoc: range.start, stmt: s, - endLoc: endLoc() + endLoc: range.end ) - out.append(topLevelDecl.asDecl) + out.append(.decl(topLevelDecl.asDecl)) case .expr(let e): + let range = getRange() let topLevelDecl = BridgedTopLevelCodeDecl.createParsed( self.ctx, declContext: self.declContext, - startLoc: loc, + startLoc: range.start, expr: e, - endLoc: endLoc() + endLoc: range.end ) - out.append(topLevelDecl.asDecl) + out.append(.decl(topLevelDecl.asDecl)) } } @@ -442,7 +449,7 @@ public func buildTopLevelASTNodes( ctx: BridgedASTContext, legacyParser: BridgedLegacyParser, outputContext: UnsafeMutableRawPointer, - callback: @convention(c) (UnsafeMutableRawPointer, UnsafeMutableRawPointer) -> Void + callback: @convention(c) (BridgedASTNode, UnsafeMutableRawPointer) -> Void ) { let sourceFile = sourceFilePtr.assumingMemoryBound(to: ExportedSourceFile.self) let visitor = ASTGenVisitor( @@ -454,8 +461,18 @@ public func buildTopLevelASTNodes( legacyParser: legacyParser ) - visitor.generate(sourceFile: sourceFile.pointee.syntax) - .forEach { callback($0.raw, outputContext) } + switch sourceFile.pointee.syntax.as(SyntaxEnum.self) { + case .sourceFile(let node): + for elem in visitor.generate(sourceFile: node) { + callback(elem.bridged, outputContext) + } + case .memberBlockItemList(let node): + for elem in visitor.generate(memberBlockItemList: node) { + callback(ASTNode.decl(elem).bridged, outputContext) + } + default: + fatalError("invalid syntax for a source file") + } // Diagnose any errors from evaluating #ifs. visitor.diagnoseAll(visitor.configuredRegions.diagnostics) diff --git a/lib/ASTGen/Sources/ASTGen/Decls.swift b/lib/ASTGen/Sources/ASTGen/Decls.swift index cd4b9da9bc5ee..d51e6b47eb501 100644 --- a/lib/ASTGen/Sources/ASTGen/Decls.swift +++ b/lib/ASTGen/Sources/ASTGen/Decls.swift @@ -117,7 +117,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -144,7 +144,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -172,7 +172,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -200,7 +200,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -230,7 +230,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -275,7 +275,7 @@ extension ASTGenVisitor { decl.asDecl.setAttrs(attrs.attributes) self.withDeclContext(decl.asDeclContext) { - decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members)) + decl.setParsedMembers(self.generate(memberBlockItemList: node.memberBlock.members).lazy.bridgedArray(in: self)) } return decl @@ -848,7 +848,7 @@ extension ASTGenVisitor { extension ASTGenVisitor { @inline(__always) - func generate(memberBlockItemList node: MemberBlockItemListSyntax) -> BridgedArrayRef { + func generate(memberBlockItemList node: MemberBlockItemListSyntax) -> [BridgedDecl] { var allBridged: [BridgedDecl] = [] visitIfConfigElements(node, of: MemberBlockItemSyntax.self) { element in if let ifConfigDecl = element.decl.as(IfConfigDeclSyntax.self) { @@ -861,7 +861,7 @@ extension ASTGenVisitor { allBridged.append(self.generate(decl: member.decl)) } - return allBridged.lazy.bridgedArray(in: self) + return allBridged } @inline(__always) diff --git a/lib/ASTGen/Sources/ASTGen/Exprs.swift b/lib/ASTGen/Sources/ASTGen/Exprs.swift index 02f79bb395f9b..7ce80e4b6f50d 100644 --- a/lib/ASTGen/Sources/ASTGen/Exprs.swift +++ b/lib/ASTGen/Sources/ASTGen/Exprs.swift @@ -172,7 +172,7 @@ extension ASTGenVisitor { case .tryExpr(let node): return self.generate(tryExpr: node) case .tupleExpr(let node): - return self.generate(tupleExpr: node).asExpr + return self.generate(tupleExpr: node) case .typeExpr(let node): return self.generate(typeExpr: node).asExpr case .unresolvedAsExpr: @@ -890,7 +890,19 @@ extension ASTGenVisitor { } } - func generate(tupleExpr node: TupleExprSyntax) -> BridgedTupleExpr { + func generate(tupleExpr node: TupleExprSyntax) -> BridgedExpr { + if node.elements.count == 1, + let first = node.elements.first, + first.label == nil, + !first.expression.is(PackExpansionExprSyntax.self) { + return BridgedParenExpr.createParsed( + self.ctx, + leftParenLoc: self.generateSourceLoc(node.leftParen), + expr: self.generate(expr: node.elements.first!.expression), + rightParenLoc: self.generateSourceLoc(node.rightParen) + ).asExpr + } + let expressions = node.elements.lazy.map { self.generate(expr: $0.expression) } @@ -912,7 +924,7 @@ extension ASTGenVisitor { labels: labels.bridgedArray(in: self), labelLocs: labelLocations.bridgedArray(in: self), rightParenLoc: self.generateSourceLoc(node.rightParen) - ) + ).asExpr } func generate(typeExpr node: TypeExprSyntax) -> BridgedTypeExpr { diff --git a/lib/ASTGen/Sources/ASTGen/SourceFile.swift b/lib/ASTGen/Sources/ASTGen/SourceFile.swift index 197c0f3044eab..7243f55fa5e4a 100644 --- a/lib/ASTGen/Sources/ASTGen/SourceFile.swift +++ b/lib/ASTGen/Sources/ASTGen/SourceFile.swift @@ -31,7 +31,7 @@ public struct ExportedSourceFile { public let fileName: String /// The syntax tree for the complete source file. - public let syntax: SourceFileSyntax + public let syntax: Syntax /// A source location converter to convert `AbsolutePosition`s in `syntax` to line/column locations. /// @@ -96,31 +96,67 @@ extension Parser.SwiftVersion { /// ExportedSourceFile instance. @_cdecl("swift_ASTGen_parseSourceFile") public func parseSourceFile( - buffer: UnsafePointer, - bufferLength: Int, - moduleName: UnsafePointer, - filename: UnsafePointer, - ctxPtr: UnsafeMutableRawPointer? + buffer: BridgedStringRef, + moduleName: BridgedStringRef, + filename: BridgedStringRef, + declContextPtr: UnsafeMutableRawPointer?, + kind: BridgedGeneratedSourceFileKind ) -> UnsafeRawPointer { - let buffer = UnsafeBufferPointer(start: buffer, count: bufferLength) + let buffer = UnsafeBufferPointer(start: buffer.data, count: buffer.count) + let dc = declContextPtr.map { BridgedDeclContext(raw: $0) } + let ctx = dc?.astContext - let ctx = ctxPtr.map { BridgedASTContext(raw: $0) } - let sourceFile = Parser.parse( - source: buffer, + var parser = Parser( + buffer, swiftVersion: Parser.SwiftVersion(from: ctx), - experimentalFeatures: .init(from: ctx) + experimentalFeatures: Parser.ExperimentalFeatures(from: ctx) ) + let parsed: Syntax + switch kind { + case .none, // Top level source file. + .expressionMacroExpansion, + .conformanceMacroExpansion, + .extensionMacroExpansion, + .preambleMacroExpansion, + .replacedFunctionBody, + .prettyPrinted, + .defaultArgument: + parsed = Syntax(SourceFileSyntax.parse(from: &parser)) + + case .declarationMacroExpansion, + .codeItemMacroExpansion, + .peerMacroExpansion: + if let dc, dc.isTypeContext { + parsed = Syntax(MemberBlockItemListSyntax.parse(from: &parser)) + } else { + parsed = Syntax(SourceFileSyntax.parse(from: &parser)) + } + + case .memberMacroExpansion: + parsed = Syntax(MemberBlockItemListSyntax.parse(from: &parser)) + + case .accessorMacroExpansion: + // FIXME: Implement specialized parsing. + parsed = Syntax(SourceFileSyntax.parse(from: &parser)) + case .memberAttributeMacroExpansion: + // FIXME: Implement specialized parsing. + parsed = Syntax(SourceFileSyntax.parse(from: &parser)) + case .bodyMacroExpansion: + // FIXME: Implement specialized parsing. + parsed = Syntax(SourceFileSyntax.parse(from: &parser)) + } + let exportedPtr = UnsafeMutablePointer.allocate(capacity: 1) - let moduleName = String(cString: moduleName) - let fileName = String(cString: filename) + let moduleName = String(bridged: moduleName) + let fileName = String(bridged: filename) exportedPtr.initialize( to: .init( buffer: buffer, moduleName: moduleName, fileName: fileName, - syntax: sourceFile, - sourceLocationConverter: SourceLocationConverter(fileName: fileName, tree: sourceFile) + syntax: parsed, + sourceLocationConverter: SourceLocationConverter(fileName: fileName, tree: parsed) ) ) diff --git a/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift b/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift index 08a2cfae9c7c4..b498dae936ec1 100644 --- a/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift +++ b/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift @@ -28,7 +28,7 @@ class SourceManager { /// The set of source files that have been exported to the C++ code of /// the program. - var exportedSourceFilesBySyntax: [SourceFileSyntax: UnsafePointer] = [:] + var exportedSourceFilesBySyntax: [Syntax: UnsafePointer] = [:] /// The set of nodes that have been detached from their parent nodes. /// @@ -46,7 +46,7 @@ extension SourceManager { /// already there. @discardableResult func insert(_ sourceFile: UnsafePointer) -> Bool { - let syntax = sourceFile.pointee.syntax + let syntax = Syntax(sourceFile.pointee.syntax) if exportedSourceFilesBySyntax[syntax] != nil { return false } @@ -80,33 +80,20 @@ extension SourceManager { /// Find the root source file and offset from within that file for the given /// syntax node. - func rootSourceFile( + func rootSyntax( of node: Node - ) -> (SourceFileSyntax, AbsolutePosition)? { - let root = node.root - - // If the root is a source file, we're done. - if let rootSF = root.as(SourceFileSyntax.self) { - return (rootSF, node.position) - } + ) -> (Syntax, AbsolutePosition) { + var root = node.root + var offset = node.position // If the root isn't a detached node we know about, there's nothing we // can do. - guard let (parent, offset) = detachedNodes[root] else { - return nil - } - - // Recursively find the root and its offset. - guard let (rootSF, parentOffset) = rootSourceFile(of: parent) else { - return nil + while let (parent, parentOffset) = detachedNodes[root] { + root = parent.root + offset += SourceLength(utf8Length: parentOffset) } - // The position of our node is... - let finalPosition = - node.position // Our position relative to its root - + SourceLength(utf8Length: offset) // and that root's offset in its parent - + SourceLength(utf8Length: parentOffset.utf8Offset) - return (rootSF, finalPosition) + return (root, offset) } /// Produce the C++ source location for a given position based on a @@ -116,13 +103,10 @@ extension SourceManager { at position: AbsolutePosition? = nil ) -> BridgedSourceLoc { // Find the source file and this node's position within it. - guard let (sourceFile, rootPosition) = rootSourceFile(of: node) else { - return nil - } + let (rootNode, rootPosition) = rootSyntax(of: node) // Find the corresponding exported source file. - guard let exportedSourceFile = exportedSourceFilesBySyntax[sourceFile] - else { + guard let exportedSourceFile = exportedSourceFilesBySyntax[rootNode] else { return nil } diff --git a/lib/DriverTool/swift_parse_test_main.cpp b/lib/DriverTool/swift_parse_test_main.cpp index 3d0a0774fd083..1e071ed314418 100644 --- a/lib/DriverTool/swift_parse_test_main.cpp +++ b/lib/DriverTool/swift_parse_test_main.cpp @@ -18,7 +18,6 @@ #include "swift/Basic/LLVM.h" #include "swift/Basic/LangOptions.h" #include "swift/Bridging/ASTGen.h" -#include "swift/Parse/Parser.h" #include "swift/Subsystems.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" @@ -86,6 +85,9 @@ struct LibParseExecutor { std::unique_ptr ctx(ASTContext::get( langOpts, typeckOpts, silOpts, searchPathOpts, clangOpts, symbolOpts, casOpts, serializationOpts, SM, diagEngine)); + auto &eval = ctx->evaluator; + registerParseRequestFunctions(eval); + registerTypeCheckerRequestFunctions(eval); SourceFile::ParsingOptions parseOpts; parseOpts |= SourceFile::ParsingFlags::DisablePoundIfEvaluation; @@ -96,13 +98,9 @@ struct LibParseExecutor { SourceFile *SF = new (*ctx) SourceFile(*M, SourceFileKind::Library, bufferID, parseOpts); - Parser parser(bufferID, *SF, /*SILParserState=*/nullptr); - SmallVector items; - parser.parseTopLevelItems(items); + auto items = evaluateOrDefault(eval, ParseSourceFileRequest{SF}, {}).TopLevelItems; if (opts.contains(ExecuteOptionFlag::Dump)) { - registerParseRequestFunctions(ctx->evaluator); - registerTypeCheckerRequestFunctions(ctx->evaluator); for (auto &item : items) { item.dump(llvm::outs()); } @@ -120,8 +118,9 @@ struct SwiftParserExecutor { #if SWIFT_BUILD_SWIFT_SYNTAX // TODO: Implement 'ExecuteOptionFlag::SkipBodies' auto sourceFile = swift_ASTGen_parseSourceFile( - buffer.getBufferStart(), buffer.getBufferSize(), /*moduleName=*/"", - buffer.getBufferIdentifier().data(), /*ASTContext=*/nullptr); + buffer.getBuffer(), + /*moduleName=*/StringRef(), buffer.getBufferIdentifier(), + /*declContextPtr=*/nullptr, BridgedGeneratedSourceFileKindNone); swift_ASTGen_destroySourceFile(sourceFile); if (opts.contains(ExecuteOptionFlag::Dump)) { @@ -162,8 +161,9 @@ struct ASTGenExecutor { std::unique_ptr ctx(ASTContext::get( langOpts, typeckOpts, silOpts, searchPathOpts, clangOpts, symbolOpts, casOpts, serializationOpts, SM, diagEngine)); - registerParseRequestFunctions(ctx->evaluator); - registerTypeCheckerRequestFunctions(ctx->evaluator); + auto &eval = ctx->evaluator; + registerParseRequestFunctions(eval); + registerTypeCheckerRequestFunctions(eval); SourceFile::ParsingOptions parseOpts; parseOpts |= SourceFile::ParsingFlags::DisablePoundIfEvaluation; @@ -174,9 +174,7 @@ struct ASTGenExecutor { SourceFile *SF = new (*ctx) SourceFile(*M, SourceFileKind::Library, bufferID, parseOpts); - Parser P(bufferID, *SF, nullptr); - SmallVector items; - P.parseTopLevelItems(items); + auto items = evaluateOrDefault(eval, ParseSourceFileRequest{SF}, {}).TopLevelItems; if (opts.contains(ExecuteOptionFlag::Dump)) { for (auto &item : items) { diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index e9f383ca6f582..9d99226b24bdc 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -162,21 +162,6 @@ namespace { }; } // end anonymous namespace -extern "C" void parseTopLevelSwift(const char *buffer, - void *declContext, - void *astContext, - void *outputContext, - void (*)(void *, void *)); - -#if SWIFT_BUILD_SWIFT_SYNTAX -static void appendToVector(void *declPtr, void *vecPtr) { - auto vec = static_cast *>(vecPtr); - auto decl = static_cast(declPtr); - - vec->push_back(decl); -} -#endif - /// Main entrypoint for the parser. /// /// \verbatim @@ -186,11 +171,6 @@ static void appendToVector(void *declPtr, void *vecPtr) { /// decl-sil-stage [[only in SIL mode] /// \endverbatim void Parser::parseTopLevelItems(SmallVectorImpl &items) { -#if SWIFT_BUILD_SWIFT_SYNTAX - std::optional existingParsingTransaction; - parseSourceFileViaASTGen(items, existingParsingTransaction); -#endif - // Prime the lexer. if (Tok.is(tok::NUM_TOKENS)) consumeTokenWithoutFeedingReceiver(); @@ -239,31 +219,16 @@ void Parser::parseTopLevelItems(SmallVectorImpl &items) { } #if SWIFT_BUILD_SWIFT_SYNTAX - if (existingParsingTransaction) - existingParsingTransaction->abort(); - using ParsingFlags = SourceFile::ParsingFlags; const auto parsingOpts = SF.getParsingOptions(); - // If we don't need to validate anything, we're done. - if (!parsingOpts.contains(ParsingFlags::RoundTrip) && - !parsingOpts.contains(ParsingFlags::ValidateNewParserDiagnostics)) { - return; - } - - auto *exportedSourceFile = SF.getExportedSourceFile(); - if (!exportedSourceFile) - return; - - // Perform round-trip and/or validation checking. - if (parsingOpts.contains(ParsingFlags::RoundTrip) && - swift_ASTGen_roundTripCheck(exportedSourceFile)) { - SourceLoc loc = Context.SourceMgr.getLocForBufferStart(SF.getBufferID()); - diagnose(loc, diag::parser_round_trip_error); - return; - } + // Perform validation checking. if (parsingOpts.contains(ParsingFlags::ValidateNewParserDiagnostics) && !Context.Diags.hadAnyError()) { + auto *exportedSourceFile = SF.getExportedSourceFile(); + if (!exportedSourceFile) + return; + auto hadSyntaxError = swift_ASTGen_emitParserDiagnostics( Context, &Context.Diags, exportedSourceFile, /*emitOnlyErrors=*/true, @@ -282,104 +247,6 @@ void Parser::parseTopLevelItems(SmallVectorImpl &items) { #endif } -void *ExportedSourceFileRequest::evaluate(Evaluator &evaluator, - const SourceFile *SF) const { -#if SWIFT_BUILD_SWIFT_SYNTAX - // The SwiftSyntax parser doesn't (yet?) handle SIL. - if (SF->Kind == SourceFileKind::SIL) - return nullptr; - - auto &ctx = SF->getASTContext(); - auto &SM = ctx.SourceMgr; - - auto bufferID = SF->getBufferID(); - StringRef contents = SM.extractText(SM.getRangeForBuffer(bufferID)); - - // Parse the source file. - auto exportedSourceFile = swift_ASTGen_parseSourceFile( - contents.begin(), contents.size(), - SF->getParentModule()->getName().str().str().c_str(), - SF->getFilename().str().c_str(), &ctx); - - ctx.addCleanup([exportedSourceFile] { - swift_ASTGen_destroySourceFile(exportedSourceFile); - }); - return exportedSourceFile; -#else - return nullptr; -#endif -} - -void Parser::parseSourceFileViaASTGen( - SmallVectorImpl &items, - std::optional &transaction, - bool suppressDiagnostics) { -#if SWIFT_BUILD_SWIFT_SYNTAX - const auto &langOpts = Context.LangOpts; - - // We only need to do parsing if we either have ASTGen enabled, or want the - // new parser diagnostics. - auto needToParse = [&]() { - if (langOpts.hasFeature(Feature::ParserASTGen)) - return true; - if (!suppressDiagnostics && - langOpts.hasFeature(Feature::ParserDiagnostics)) { - return true; - } - return false; - }(); - if (!needToParse) - return; - - switch (SF.Kind) { - case SourceFileKind::Library: - case SourceFileKind::Main: - case SourceFileKind::Interface: - break; - case SourceFileKind::SIL: - // FIXME: Support SIL. - return; - case SourceFileKind::MacroExpansion: - case SourceFileKind::DefaultArgument: - // FIXME: Support macro expanded sources. - return; - } - - auto *exportedSourceFile = SF.getExportedSourceFile(); - if (!exportedSourceFile) - return; - - // If we're supposed to emit diagnostics from the parser, do so now. - if (!suppressDiagnostics) { - auto hadSyntaxError = swift_ASTGen_emitParserDiagnostics( - Context, &Context.Diags, exportedSourceFile, /*emitOnlyErrors=*/false, - /*downgradePlaceholderErrorsToWarnings=*/langOpts.Playground || - langOpts.WarnOnEditorPlaceholder); - if (hadSyntaxError && Context.Diags.hadAnyError() && - !langOpts.hasFeature(Feature::ParserASTGen)) { - // Errors were emitted, and we're still using the C++ parser, so - // disable diagnostics from the C++ parser. - transaction.emplace(Context.Diags); - } - } - - // If we want to do ASTGen, do so now. - if (langOpts.hasFeature(Feature::ParserASTGen)) { - this->IsForASTGen = true; - swift_ASTGen_buildTopLevelASTNodes(&Diags, exportedSourceFile, - CurDeclContext, Context, *this, &items, - appendToVector); - - // Spin the C++ parser to the end; we won't be using it. - DiagnosticTransaction noDiag(Context.Diags); - while (!Tok.is(tok::eof)) { - consumeToken(); - } - noDiag.abort(); - } -#endif -} - bool Parser::parseTopLevelSIL() { assert(SIL && isInSILMode()); @@ -8285,9 +8152,6 @@ void Parser::parseTopLevelAccessors( } void Parser::parseExpandedAttributeList(SmallVectorImpl &items) { - std::optional transaction; - parseSourceFileViaASTGen(items, transaction, /*suppressDiagnostics*/true); - if (Tok.is(tok::NUM_TOKENS)) consumeTokenWithoutFeedingReceiver(); @@ -8312,9 +8176,6 @@ void Parser::parseExpandedAttributeList(SmallVectorImpl &items) { } void Parser::parseExpandedMemberList(SmallVectorImpl &items) { - std::optional transaction; - parseSourceFileViaASTGen(items, transaction, /*suppressDiagnostics*/true); - if (Tok.is(tok::NUM_TOKENS)) consumeTokenWithoutFeedingReceiver(); diff --git a/lib/Parse/ParseRequests.cpp b/lib/Parse/ParseRequests.cpp index 86fe3f2322368..48d16c921e897 100644 --- a/lib/Parse/ParseRequests.cpp +++ b/lib/Parse/ParseRequests.cpp @@ -21,6 +21,7 @@ #include "swift/AST/SourceFile.h" #include "swift/Basic/Assertions.h" #include "swift/Basic/Defer.h" +#include "swift/Bridging/ASTGen.h" #include "swift/Parse/Parser.h" #include "swift/Subsystems.h" @@ -127,39 +128,168 @@ ParseAbstractFunctionBodyRequest::evaluate(Evaluator &evaluator, } //----------------------------------------------------------------------------// -// ParseSourceFileRequest computation. +// ExportedSourceFileRequest computation. //----------------------------------------------------------------------------// -/// A thunk that deletes an allocated PersistentParserState. This is needed for -/// us to be able to forward declare a unique_ptr to the state in the AST. -static void deletePersistentParserState(PersistentParserState *state) { - delete state; +static BridgedGeneratedSourceFileKind +getBridgedGeneratedSourceFileKind(const GeneratedSourceInfo *genInfo) { + if (!genInfo) + return BridgedGeneratedSourceFileKindNone; + + switch (genInfo->kind) { + +#define MACRO_ROLE(Name, Description) \ + case GeneratedSourceInfo::Kind::Name##MacroExpansion: \ + return BridgedGeneratedSourceFileKind##Name##MacroExpansion; +#include "swift/Basic/MacroRoles.def" +#undef MACRO_ROLE + + case GeneratedSourceInfo::Kind::ReplacedFunctionBody: + return BridgedGeneratedSourceFileKindReplacedFunctionBody; + case GeneratedSourceInfo::Kind::PrettyPrinted: + return BridgedGeneratedSourceFileKindPrettyPrinted; + case GeneratedSourceInfo::Kind::DefaultArgument: + return BridgedGeneratedSourceFileKindDefaultArgument; + } } -SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator, - SourceFile *SF) const { - assert(SF); +void *ExportedSourceFileRequest::evaluate(Evaluator &evaluator, + const SourceFile *SF) const { +#if SWIFT_BUILD_SWIFT_SYNTAX + // The SwiftSyntax parser doesn't (yet?) handle SIL. + if (SF->Kind == SourceFileKind::SIL) + return nullptr; + auto &ctx = SF->getASTContext(); - auto bufferID = SF->getBufferID(); - // If we've been asked to silence warnings, do so now. This is needed for - // secondary files, which can be parsed multiple times. - auto &diags = ctx.Diags; - auto didSuppressWarnings = diags.getSuppressWarnings(); - auto shouldSuppress = SF->getParsingOptions().contains( - SourceFile::ParsingFlags::SuppressWarnings); - diags.setSuppressWarnings(didSuppressWarnings || shouldSuppress); - SWIFT_DEFER { diags.setSuppressWarnings(didSuppressWarnings); }; + const auto *genInfo = SF->getGeneratedSourceFileInfo(); + DeclContext *dc = const_cast(SF); + if (genInfo && genInfo->declContext) + dc = genInfo->declContext; + + // Parse the source file. + auto exportedSourceFile = swift_ASTGen_parseSourceFile( + SF->getBuffer(), SF->getParentModule()->getName().str(), + SF->getFilename(), dc, getBridgedGeneratedSourceFileKind(genInfo)); + + // Round-trip validation if needed. + if (SF->getParsingOptions().contains(SourceFile::ParsingFlags::RoundTrip)) { + if (swift_ASTGen_roundTripCheck(exportedSourceFile)) { + SourceLoc loc = ctx.SourceMgr.getLocForBufferStart(SF->getBufferID()); + ctx.Diags.diagnose(loc, diag::parser_round_trip_error); + } + } + + ctx.addCleanup([exportedSourceFile] { + swift_ASTGen_destroySourceFile(exportedSourceFile); + }); + return exportedSourceFile; +#else + return nullptr; +#endif // SWIFT_BUILD_SWIFT_SYNTAX +} + +//----------------------------------------------------------------------------// +// ParseSourceFileRequest computation. +//----------------------------------------------------------------------------// + +namespace { + +#if SWIFT_BUILD_SWIFT_SYNTAX +/// Whether we can "parse" the source file via ASTGen. +bool shouldParseViaASTGen(SourceFile &SF) { + auto &ctx = SF.getASTContext(); + auto &langOpts = ctx.LangOpts; + + if (!langOpts.hasFeature(Feature::ParserASTGen)) + return false; + + switch (SF.Kind) { + case SourceFileKind::SIL: + return false; + case SourceFileKind::Library: + case SourceFileKind::Main: + case SourceFileKind::Interface: + case SourceFileKind::MacroExpansion: + case SourceFileKind::DefaultArgument: + break; + } + + // TODO: Migrate SourceKit features to Syntax based. + if (SF.shouldCollectTokens()) + return false; + + // TODO: Implement DebuggerContextChange in ASTGen. + if (langOpts.DebuggerSupport) + return false; + + // TODO: IDE inspection (code completion) support in ASTGen. + if (ctx.SourceMgr.getIDEInspectionTargetBufferID() == SF.getBufferID()) + return false; + + return true; +} + +void appendToVector(BridgedASTNode cNode, void *vecPtr) { + auto vec = static_cast *>(vecPtr); + vec->push_back(cNode.unbridged()); +} + +SourceFileParsingResult parseSourceFileViaASTGen(SourceFile &SF) { + Parser legacyParser(SF.getBufferID(), SF, /*SIL=*/nullptr, + /*PersistentState=*/nullptr); + legacyParser.IsForASTGen = true; + + ASTContext &Ctx = SF.getASTContext(); + DiagnosticEngine &Diags = Ctx.Diags; + const LangOptions &langOpts = Ctx.LangOpts; + const GeneratedSourceInfo *genInfo = SF.getGeneratedSourceFileInfo(); + + DeclContext *declContext = &SF; + if (genInfo && genInfo->declContext) { + declContext = genInfo->declContext; + } + + // Parse the file. + auto *exportedSourceFile = SF.getExportedSourceFile(); + assert(exportedSourceFile && "Couldn't parse via SyntaxParser"); + + // Emit parser diagnostics. + (void)swift_ASTGen_emitParserDiagnostics( + Ctx, &Diags, exportedSourceFile, /*emitOnlyErrors=*/false, + /*downgradePlaceholderErrorsToWarnings=*/langOpts.Playground || + langOpts.WarnOnEditorPlaceholder); + + // Generate AST nodes. + SmallVector items; + swift_ASTGen_buildTopLevelASTNodes( + &Diags, exportedSourceFile, declContext, Ctx, legacyParser, + static_cast *>(&items), appendToVector); + + return SourceFileParsingResult{/*TopLevelItems=*/Ctx.AllocateCopy(items), + /*CollectedTokens=*/std::nullopt, + // FIXME: Implement interface hash. + /*InterfaceHasher=*/std::nullopt}; +} +#endif // SWIFT_BUILD_SWIFT_SYNTAX + +/// A thunk that deletes an allocated PersistentParserState. This is needed for +/// us to be able to forward declare a unique_ptr to the state in the AST. +void deletePersistentParserState(PersistentParserState *state) { delete state; } + +SourceFileParsingResult parseSourceFile(SourceFile &SF) { + auto &ctx = SF.getASTContext(); + auto bufferID = SF.getBufferID(); // If this buffer is for IDE functionality, hook up the state needed by its // second pass. PersistentParserState *state = nullptr; if (ctx.SourceMgr.getIDEInspectionTargetBufferID() == bufferID) { state = new PersistentParserState(); - SF->setDelayedParserState({state, &deletePersistentParserState}); + SF.setDelayedParserState({state, &deletePersistentParserState}); } - Parser parser(bufferID, *SF, /*SIL*/ nullptr, state); + Parser parser(bufferID, SF, /*SIL*/ nullptr, state); PrettyStackTraceParser StackTrace(parser); // If the buffer is generated source information, we might have more @@ -249,6 +379,30 @@ SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator, parser.CurrentTokenHash}; } +} // namespace + +SourceFileParsingResult ParseSourceFileRequest::evaluate(Evaluator &evaluator, + SourceFile *SF) const { + assert(SF); + auto &ctx = SF->getASTContext(); + + // If we've been asked to silence warnings, do so now. This is needed for + // secondary files, which can be parsed multiple times. + auto &diags = ctx.Diags; + auto didSuppressWarnings = diags.getSuppressWarnings(); + auto shouldSuppress = SF->getParsingOptions().contains( + SourceFile::ParsingFlags::SuppressWarnings); + diags.setSuppressWarnings(didSuppressWarnings || shouldSuppress); + SWIFT_DEFER { diags.setSuppressWarnings(didSuppressWarnings); }; + +#if SWIFT_BUILD_SWIFT_SYNTAX + if (shouldParseViaASTGen(*SF)) + return parseSourceFileViaASTGen(*SF); +#endif + + return parseSourceFile(*SF); +} + evaluator::DependencySource ParseSourceFileRequest::readDependencySource( const evaluator::DependencyRecorder &e) const { return std::get<0>(getStorage()); diff --git a/test/ASTGen/diagnostics.swift b/test/ASTGen/diagnostics.swift index 99cd5a1ee9285..f7ea9cbe2493c 100644 --- a/test/ASTGen/diagnostics.swift +++ b/test/ASTGen/diagnostics.swift @@ -27,3 +27,7 @@ func testEditorPlaceholder() -> Int { foo(<#T##x: String##String#>) // expected-error {{editor placeholder in source file}}) return <#T##Int#> // expected-error {{editor placeholder in source file}} } + +_ = [(Int) -> async throws Int]() +// expected-error@-1{{'async throws' must precede '->'}} +// expected-note@-2{{move 'async throws' in front of '->'}}{{15-21=}} {{21-28=}} {{20-21= }} {{12-12=async }} {{12-12=throws }} diff --git a/test/Parse/new_parser_diagnostics.swift b/test/Parse/new_parser_diagnostics.swift deleted file mode 100644 index c723addd35a9c..0000000000000 --- a/test/Parse/new_parser_diagnostics.swift +++ /dev/null @@ -1,8 +0,0 @@ -// REQUIRES: swift_swift_parser -// REQUIRES: swift_feature_ParserDiagnostics - -// RUN: %target-typecheck-verify-swift -enable-experimental-feature ParserDiagnostics - -_ = [(Int) -> async throws Int]() -// expected-error@-1{{'async throws' must precede '->'}} -// expected-note@-2{{move 'async throws' in front of '->'}}{{15-21=}} {{21-28=}} {{20-21= }} {{12-12=async }} {{12-12=throws }}