diff --git a/include/swift/AST/CASTBridging.h b/include/swift/AST/CASTBridging.h index d068c26b928ad..2d6a5a7409113 100644 --- a/include/swift/AST/CASTBridging.h +++ b/include/swift/AST/CASTBridging.h @@ -247,6 +247,9 @@ void Diagnostic_finish(BridgedDiagnostic cDiag); BridgedIdentifier ASTContext_getIdentifier(BridgedASTContext cContext, BridgedString cStr); +_Bool ASTContext_langOptsHasFeature(BridgedASTContext cContext, + BridgedFeature feature); + void *ImportDecl_create(BridgedASTContext cContext, BridgedDeclContext cDeclContext, BridgedSourceLoc cImportLoc, char kind, diff --git a/include/swift/Basic/CBasicBridging.h b/include/swift/Basic/CBasicBridging.h index 0425b6b67c33b..1a99b83c703c2 100644 --- a/include/swift/Basic/CBasicBridging.h +++ b/include/swift/Basic/CBasicBridging.h @@ -22,7 +22,6 @@ // layering. i.e. Darwin overlay is created by Swift compiler. SWIFT_BEGIN_NULLABILITY_ANNOTATIONS -SWIFT_BEGIN_ASSUME_NONNULL #ifdef __cplusplus extern "C" { @@ -31,6 +30,14 @@ extern "C" { #endif +typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedFeature { +#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option) \ +FeatureName, +#include "swift/Basic/Features.def" +} BridgedFeature; + +SWIFT_BEGIN_ASSUME_NONNULL + typedef struct BridgedData { const char *_Nullable baseAddress; unsigned long size; diff --git a/lib/AST/CASTBridging.cpp b/lib/AST/CASTBridging.cpp index 50215828c43bf..e629b4057b0e9 100644 --- a/lib/AST/CASTBridging.cpp +++ b/lib/AST/CASTBridging.cpp @@ -176,6 +176,11 @@ BridgedIdentifier ASTContext_getIdentifier(BridgedASTContext cContext, return {convertASTContext(cContext).getIdentifier(str).getAsOpaquePointer()}; } +bool ASTContext_langOptsHasFeature(BridgedASTContext cContext, + BridgedFeature feature) { + return convertASTContext(cContext).LangOpts.hasFeature((Feature)feature); +} + void *ImportDecl_create(BridgedASTContext cContext, BridgedDeclContext cDeclContext, BridgedSourceLoc cImportLoc, char kind, diff --git a/lib/ASTGen/Sources/ASTGen/ASTGen.swift b/lib/ASTGen/Sources/ASTGen/ASTGen.swift index 5cfedde85a4d6..7d726f002b081 100644 --- a/lib/ASTGen/Sources/ASTGen/ASTGen.swift +++ b/lib/ASTGen/Sources/ASTGen/ASTGen.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension Array { diff --git a/lib/ASTGen/Sources/ASTGen/Decls.swift b/lib/ASTGen/Sources/ASTGen/Decls.swift index 18241bac0711b..8f882925dae61 100644 --- a/lib/ASTGen/Sources/ASTGen/Decls.swift +++ b/lib/ASTGen/Sources/ASTGen/Decls.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/ASTGen/Sources/ASTGen/Exprs.swift b/lib/ASTGen/Sources/ASTGen/Exprs.swift index 636c9ee6d3d78..4b909ac3a32c3 100644 --- a/lib/ASTGen/Sources/ASTGen/Exprs.swift +++ b/lib/ASTGen/Sources/ASTGen/Exprs.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/ASTGen/Sources/ASTGen/Generics.swift b/lib/ASTGen/Sources/ASTGen/Generics.swift index 6893f184d59c2..cba550688b75e 100644 --- a/lib/ASTGen/Sources/ASTGen/Generics.swift +++ b/lib/ASTGen/Sources/ASTGen/Generics.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/ASTGen/Sources/ASTGen/Macros.swift b/lib/ASTGen/Sources/ASTGen/Macros.swift index 1c0df4f427261..96205f1d149e9 100644 --- a/lib/ASTGen/Sources/ASTGen/Macros.swift +++ b/lib/ASTGen/Sources/ASTGen/Macros.swift @@ -14,12 +14,15 @@ import CASTBridging import SwiftDiagnostics import SwiftOperators import SwiftParser -import SwiftSyntax import SwiftSyntaxBuilder import SwiftSyntaxMacros import SwiftSyntaxMacroExpansion import SwiftCompilerPluginMessageHandling +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) +import SwiftSyntax + extension SyntaxProtocol { func token(at position: AbsolutePosition) -> TokenSyntax? { // If the position isn't within this node at all, return early. diff --git a/lib/ASTGen/Sources/ASTGen/Misc.swift b/lib/ASTGen/Sources/ASTGen/Misc.swift index 9ccb04c0703c1..acc15c8b8bca5 100644 --- a/lib/ASTGen/Sources/ASTGen/Misc.swift +++ b/lib/ASTGen/Sources/ASTGen/Misc.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/ASTGen/Sources/ASTGen/SourceFile.swift b/lib/ASTGen/Sources/ASTGen/SourceFile.swift index 227f00e83e75c..5fc97b01503ca 100644 --- a/lib/ASTGen/Sources/ASTGen/SourceFile.swift +++ b/lib/ASTGen/Sources/ASTGen/SourceFile.swift @@ -1,8 +1,13 @@ +import CBasicBridging +import CASTBridging + import SwiftDiagnostics -import SwiftParser import SwiftSyntax import SwiftParserDiagnostics +@_spi(ExperimentalLanguageFeatures) +import SwiftParser + /// Describes a source file that has been "exported" to the C++ part of the /// compiler, with enough information to interface with the C++ layer. struct ExportedSourceFile { @@ -20,15 +25,31 @@ struct ExportedSourceFile { let syntax: SourceFileSyntax } +extension Parser.ExperimentalFeatures { + init(from context: BridgedASTContext?) { + self = [] + guard let context = context else { return } + + func mapFeature(_ bridged: BridgedFeature, to feature: Self) { + if ASTContext_langOptsHasFeature(context, bridged) { + insert(feature) + } + } + } +} + /// Parses the given source file and produces a pointer to a new /// ExportedSourceFile instance. @_cdecl("swift_ASTGen_parseSourceFile") public func parseSourceFile( buffer: UnsafePointer, bufferLength: Int, - moduleName: UnsafePointer, filename: UnsafePointer + moduleName: UnsafePointer, filename: UnsafePointer, + ctxPtr: UnsafeMutableRawPointer? ) -> UnsafeRawPointer { let buffer = UnsafeBufferPointer(start: buffer, count: bufferLength) - let sourceFile = Parser.parse(source: buffer) + + let ctx = ctxPtr.map { BridgedASTContext(raw: $0) } + let sourceFile = Parser.parse(source: buffer, experimentalFeatures: .init(from: ctx)) let exportedPtr = UnsafeMutablePointer.allocate(capacity: 1) exportedPtr.initialize( diff --git a/lib/ASTGen/Sources/ASTGen/Stmts.swift b/lib/ASTGen/Sources/ASTGen/Stmts.swift index 5b32bd6611270..5a78ebcf5978a 100644 --- a/lib/ASTGen/Sources/ASTGen/Stmts.swift +++ b/lib/ASTGen/Sources/ASTGen/Stmts.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/ASTGen/Sources/ASTGen/Types.swift b/lib/ASTGen/Sources/ASTGen/Types.swift index 6d8dd8aeb304b..df0c9fef326dc 100644 --- a/lib/ASTGen/Sources/ASTGen/Types.swift +++ b/lib/ASTGen/Sources/ASTGen/Types.swift @@ -1,5 +1,8 @@ import CASTBridging import SwiftParser + +// Needed to use SyntaxTransformVisitor's visit method. +@_spi(SyntaxTransformVisitor) import SwiftSyntax extension ASTGenVisitor { diff --git a/lib/Frontend/PrintingDiagnosticConsumer.cpp b/lib/Frontend/PrintingDiagnosticConsumer.cpp index 36a1f47421326..828fdcce4d7e7 100644 --- a/lib/Frontend/PrintingDiagnosticConsumer.cpp +++ b/lib/Frontend/PrintingDiagnosticConsumer.cpp @@ -60,7 +60,8 @@ extern "C" void swift_ASTGen_renderQueuedDiagnostics( extern "C" void *swift_ASTGen_parseSourceFile(const char *buffer, size_t bufferLength, const char *moduleName, - const char *filename); + const char *filename, + void *_Nullable ctx); extern "C" void swift_ASTGen_destroySourceFile(void *sourceFile); namespace { @@ -1047,7 +1048,7 @@ void PrintingDiagnosticConsumer::queueBuffer( auto bufferContents = sourceMgr.getEntireTextForBuffer(bufferID); auto sourceFile = swift_ASTGen_parseSourceFile( bufferContents.data(), bufferContents.size(), - "module", "file.swift"); + "module", "file.swift", /*ctx*/ nullptr); // Find the parent and position in parent, if there is one. int parentID = -1; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 6a30f5c6a3b73..fcdef55ad6032 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -16,6 +16,7 @@ #include "swift/AST/ASTWalker.h" #include "swift/AST/Attr.h" +#include "swift/AST/CASTBridging.h" #include "swift/AST/DebuggerClient.h" #include "swift/AST/Decl.h" #include "swift/AST/DiagnosticsParse.h" @@ -175,7 +176,8 @@ static void appendToVector(void *declPtr, void *vecPtr) { extern "C" void *swift_ASTGen_parseSourceFile(const char *buffer, size_t bufferLength, const char *moduleName, - const char *filename); + const char *filename, + void *_Nullable ctx); /// Destroy a source file parsed with swift_ASTGen_parseSourceFile. extern "C" void swift_ASTGen_destroySourceFile(void *sourceFile); @@ -328,7 +330,7 @@ void *ExportedSourceFileRequest::evaluate(Evaluator &evaluator, auto exportedSourceFile = swift_ASTGen_parseSourceFile( contents.begin(), contents.size(), SF->getParentModule()->getName().str().str().c_str(), - SF->getFilename().str().c_str()); + SF->getFilename().str().c_str(), &ctx); ctx.addCleanup([exportedSourceFile] { swift_ASTGen_destroySourceFile(exportedSourceFile);