Skip to content

[ASTGen] Allow querying of experimental features #67826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/CASTBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 8 additions & 1 deletion include/swift/Basic/CBasicBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand All @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions lib/AST/CASTBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/ASTGen.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension Array {
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Decls.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Exprs.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Generics.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
5 changes: 4 additions & 1 deletion lib/ASTGen/Sources/ASTGen/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Misc.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
27 changes: 24 additions & 3 deletions lib/ASTGen/Sources/ASTGen/SourceFile.swift
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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)
}
}
Comment on lines +33 to +37
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is a stub to be used once you introduce features that need to be mapped to SwiftParser, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah

}
}

/// Parses the given source file and produces a pointer to a new
/// ExportedSourceFile instance.
@_cdecl("swift_ASTGen_parseSourceFile")
public func parseSourceFile(
buffer: UnsafePointer<UInt8>, bufferLength: Int,
moduleName: UnsafePointer<UInt8>, filename: UnsafePointer<UInt8>
moduleName: UnsafePointer<UInt8>, filename: UnsafePointer<UInt8>,
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<ExportedSourceFile>.allocate(capacity: 1)
exportedPtr.initialize(
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Stmts.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
3 changes: 3 additions & 0 deletions lib/ASTGen/Sources/ASTGen/Types.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import CASTBridging
import SwiftParser

// Needed to use SyntaxTransformVisitor's visit method.
@_spi(SyntaxTransformVisitor)
import SwiftSyntax

extension ASTGenVisitor {
Expand Down
5 changes: 3 additions & 2 deletions lib/Frontend/PrintingDiagnosticConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down