mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Macros] Feed the static build configuration into macro expansions
Thread the static build configuration (formed from language options) in to the macro plugin handler, which will serialize it for use in the macro implementation. test this with a simple macro that checks whether a particular custom configuration (set via `-D`) is enabled or not. This required some re-layering, sinking the logic for building a StaticBuildConfiguration from language options down into a new swiftBasicSwift library, which sits on top of the C++ swiftBasic and provides Swift functionality for it. That can be used by the C++ swiftAST to cache the StaticBuildConfiguration on the ASTContext, making it available for other parts of ASTGen.
This commit is contained in:
@@ -194,115 +194,6 @@ BridgedDeclNameLoc_createParsed(BridgedASTContext cContext,
|
||||
swift::SourceLoc moduleSelectorLoc,
|
||||
swift::SourceLoc baseNameLoc);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MARK: LangOptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t {
|
||||
EndianLittle,
|
||||
EndianBig,
|
||||
};
|
||||
|
||||
class BridgedLangOptions {
|
||||
const swift::LangOptions * _Nonnull LangOpts;
|
||||
|
||||
public:
|
||||
SWIFT_UNAVAILABLE("Use init(raw:) instead")
|
||||
BRIDGED_INLINE BridgedLangOptions(const swift::LangOptions &langOpts);
|
||||
|
||||
SWIFT_UNAVAILABLE("Use '.raw' instead")
|
||||
BRIDGED_INLINE const swift::LangOptions &unbridged() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
const void *_Nonnull getRaw() const { return LangOpts; }
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
unsigned getMajorLanguageVersion() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
unsigned getTargetPointerBitWidth() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
BridgedEndianness getTargetEndianness() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
bool getAttachCommentsToDecls() const;
|
||||
};
|
||||
|
||||
/// Key used when enumerating build configuration entries to the
|
||||
/// StaticBuildConfiguration initializer for an ASTContext.
|
||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BuildConfigurationKey : size_t {
|
||||
BCKCustomCondition,
|
||||
BCKFeature,
|
||||
BCKAttribute,
|
||||
BCKTargetOSName,
|
||||
BCKTargetArchitecture,
|
||||
BCKTargetEnvironment,
|
||||
BCKTargetRuntime,
|
||||
BCKTargetPointerAuthenticationScheme,
|
||||
BCKTargetObjectFileFormat
|
||||
};
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)")
|
||||
bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts,
|
||||
BridgedFeature feature);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)")
|
||||
bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)")
|
||||
bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasAttributeNamed(self:_:)")
|
||||
bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getLanguageVersion(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getCompilerVersion(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
/* Deallocate an array of Swift int values that was allocated in C++. */
|
||||
void deallocateIntBuffer(SwiftInt * _Nullable cComponents);
|
||||
|
||||
/// Enumerate all of the key/value pairs for the build configuration by calling
|
||||
/// the given callback for each one.
|
||||
SWIFT_NAME("BridgedLangOptions.enumerateBuildConfigurationEntries(self:callbackContext:callback:)")
|
||||
void BridgedLangOptions_enumerateBuildConfigurationEntries(
|
||||
BridgedLangOptions cLangOpts,
|
||||
void * _Nonnull callbackContext,
|
||||
void (* _Nonnull callback)(
|
||||
BridgedLangOptions cLangOpts, void * _Nonnull callbackContext,
|
||||
BuildConfigurationKey key, BridgedStringRef value));
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MARK: ASTContext
|
||||
@@ -326,6 +217,9 @@ public:
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
BridgedAvailabilityMacroMap getAvailabilityMacroMap() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
BridgedDiagnosticEngine getDiags() const;
|
||||
};
|
||||
|
||||
#define IDENTIFIER_WITH_NAME(Name, _) \
|
||||
@@ -360,6 +254,10 @@ BridgedASTContext_getDollarIdentifier(BridgedASTContext cContext, size_t idx);
|
||||
SWIFT_NAME("getter:BridgedASTContext.langOpts(self:)")
|
||||
BridgedLangOptions BridgedASTContext_langOpts(BridgedASTContext cContext);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasAttributeNamed(self:_:)")
|
||||
bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedCanImportVersion : size_t {
|
||||
CanImportUnversioned,
|
||||
CanImportVersion,
|
||||
@@ -374,6 +272,9 @@ bool BridgedASTContext_canImport(BridgedASTContext cContext,
|
||||
const SwiftInt *_Nullable versionComponents,
|
||||
SwiftInt numVersionComponents);
|
||||
|
||||
SWIFT_NAME("getter:BridgedASTContext.staticBuildConfigurationPtr(self:)")
|
||||
void * _Nonnull BridgedASTContext_staticBuildConfiguration(BridgedASTContext cContext);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MARK: AST nodes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -84,6 +84,10 @@ struct ASTContext::GlobalCache {
|
||||
const NormalProtocolConformance *,
|
||||
std::vector<ConformanceIsolationError>
|
||||
> conformanceIsolationErrors;
|
||||
|
||||
/// The static build configuration. This points to an instance of the Swift
|
||||
/// StaticBuildConfiguration.
|
||||
void *StaticBuildConfiguration = nullptr;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
||||
@@ -61,6 +61,7 @@ class VersionTuple;
|
||||
} // end namespace llvm
|
||||
|
||||
namespace swift {
|
||||
class LangOptions;
|
||||
class SourceLoc;
|
||||
class SourceRange;
|
||||
class CharSourceRange;
|
||||
@@ -451,6 +452,112 @@ struct BridgedSwiftClosure {
|
||||
BRIDGED_INLINE void operator()(const void *_Nullable);
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MARK: LangOptions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t {
|
||||
EndianLittle,
|
||||
EndianBig,
|
||||
};
|
||||
|
||||
class BridgedLangOptions {
|
||||
const swift::LangOptions * _Nonnull LangOpts;
|
||||
|
||||
public:
|
||||
SWIFT_UNAVAILABLE("Use init(raw:) instead")
|
||||
BRIDGED_INLINE BridgedLangOptions(const swift::LangOptions &langOpts);
|
||||
|
||||
SWIFT_UNAVAILABLE("Use '.raw' instead")
|
||||
BRIDGED_INLINE const swift::LangOptions &unbridged() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
const void *_Nonnull getRaw() const { return LangOpts; }
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
unsigned getMajorLanguageVersion() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
unsigned getTargetPointerBitWidth() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
BridgedEndianness getTargetEndianness() const;
|
||||
|
||||
SWIFT_COMPUTED_PROPERTY
|
||||
bool getAttachCommentsToDecls() const;
|
||||
};
|
||||
|
||||
/// Key used when enumerating build configuration entries to the
|
||||
/// StaticBuildConfiguration initializer for an ASTContext.
|
||||
enum ENUM_EXTENSIBILITY_ATTR(closed) BuildConfigurationKey : size_t {
|
||||
BCKCustomCondition,
|
||||
BCKFeature,
|
||||
BCKAttribute,
|
||||
BCKTargetOSName,
|
||||
BCKTargetArchitecture,
|
||||
BCKTargetEnvironment,
|
||||
BCKTargetRuntime,
|
||||
BCKTargetPointerAuthenticationScheme,
|
||||
BCKTargetObjectFileFormat
|
||||
};
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)")
|
||||
bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts,
|
||||
BridgedFeature feature);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)")
|
||||
bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)")
|
||||
bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)")
|
||||
bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getLanguageVersion(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
SWIFT_NAME("BridgedLangOptions.getCompilerVersion(self:_:)")
|
||||
SwiftInt BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts,
|
||||
SwiftInt* _Nullable * _Nonnull cComponents);
|
||||
|
||||
/* Deallocate an array of Swift int values that was allocated in C++. */
|
||||
void deallocateIntBuffer(SwiftInt * _Nullable cComponents);
|
||||
|
||||
/// Enumerate all of the key/value pairs for the build configuration by calling
|
||||
/// the given callback for each one.
|
||||
SWIFT_NAME("BridgedLangOptions.enumerateBuildConfigurationEntries(self:callbackContext:callback:)")
|
||||
void BridgedLangOptions_enumerateBuildConfigurationEntries(
|
||||
BridgedLangOptions cLangOpts,
|
||||
void * _Nonnull callbackContext,
|
||||
void (* _Nonnull callback)(
|
||||
BridgedLangOptions cLangOpts, void * _Nonnull callbackContext,
|
||||
BuildConfigurationKey key, BridgedStringRef value));
|
||||
|
||||
SWIFT_END_NULLABILITY_ANNOTATIONS
|
||||
|
||||
#ifndef PURE_BRIDGING_MODE
|
||||
|
||||
32
include/swift/Bridging/BasicSwift.h
Normal file
32
include/swift/Bridging/BasicSwift.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//===--- BasicSwift.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2023 - 2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_BRIDGING_BASICSWIFT_H
|
||||
#define SWIFT_BRIDGING_BASICSWIFT_H
|
||||
|
||||
#include "swift/Basic/BasicBridging.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Create a new static build configuration for the given language options.
|
||||
void * _Nonnull swift_Basic_createStaticBuildConfiguration(BridgedLangOptions cLangOpts);
|
||||
|
||||
/// Free the given static build configuration.
|
||||
void swift_Basic_freeStaticBuildConfiguration(void * _Nonnull staticBuildConfiguration);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SWIFT_BRIDGING_BASICSWIFT_H
|
||||
@@ -14,6 +14,7 @@
|
||||
#define SWIFT_BRIDGING_MACROS_H
|
||||
|
||||
#include "swift/Basic/BasicBridging.h"
|
||||
#include "swift/AST/ASTBridging.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -40,13 +41,13 @@ void swift_Macros_freeExpansionReplacements(
|
||||
ptrdiff_t *_Nullable replacementsPtr, ptrdiff_t numReplacements);
|
||||
|
||||
ptrdiff_t swift_Macros_expandFreestandingMacro(
|
||||
void *_Nonnull diagEngine, const void *_Nonnull macro,
|
||||
BridgedASTContext cContext, const void *_Nonnull macro,
|
||||
const char *_Nonnull discriminator, uint8_t rawMacroRole,
|
||||
void *_Nonnull sourceFile, const void *_Nullable sourceLocation,
|
||||
BridgedStringRef *_Nonnull evaluatedSourceOut);
|
||||
|
||||
ptrdiff_t swift_Macros_expandAttachedMacro(
|
||||
void *_Nonnull diagEngine, const void *_Nonnull macro,
|
||||
BridgedASTContext cContext, const void *_Nonnull macro,
|
||||
const char *_Nonnull discriminator, const char *_Nonnull qualifiedType,
|
||||
const char *_Nonnull conformances, uint8_t rawMacroRole,
|
||||
void *_Nonnull customAttrSourceFile,
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include "swift/AST/ASTBridging.h"
|
||||
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ASTContextGlobalCache.h"
|
||||
#include "swift/AST/AvailabilitySpec.h"
|
||||
#include "swift/Bridging/BasicSwift.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
@@ -44,6 +46,10 @@ unsigned BridgedASTContext::getMajorLanguageVersion() const {
|
||||
return unbridged().LangOpts.EffectiveLanguageVersion[0];
|
||||
}
|
||||
|
||||
BridgedDiagnosticEngine BridgedASTContext::getDiags() const {
|
||||
return &unbridged().Diags;
|
||||
}
|
||||
|
||||
bool BridgedASTContext_canImport(BridgedASTContext cContext,
|
||||
BridgedStringRef importPath,
|
||||
SourceLoc canImportLoc,
|
||||
@@ -82,3 +88,22 @@ bool BridgedASTContext_canImport(BridgedASTContext cContext,
|
||||
BridgedAvailabilityMacroMap BridgedASTContext::getAvailabilityMacroMap() const {
|
||||
return &unbridged().getAvailabilityMacroMap();
|
||||
}
|
||||
|
||||
bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName) {
|
||||
return hasAttribute(cLangOpts.unbridged(), cName.unbridged());
|
||||
}
|
||||
|
||||
void *BridgedASTContext_staticBuildConfiguration(BridgedASTContext cContext) {
|
||||
ASTContext &ctx = cContext.unbridged();
|
||||
void *staticBuildConfiguration = ctx.getGlobalCache().StaticBuildConfiguration;
|
||||
if (!staticBuildConfiguration) {
|
||||
staticBuildConfiguration =
|
||||
swift_Basic_createStaticBuildConfiguration(ctx.LangOpts);
|
||||
ctx.addCleanup([staticBuildConfiguration] {
|
||||
swift_Basic_freeStaticBuildConfiguration(staticBuildConfiguration);
|
||||
});
|
||||
}
|
||||
|
||||
return staticBuildConfiguration;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ target_sources(swiftAST PRIVATE
|
||||
DiagnosticsBridging.cpp
|
||||
ExprBridging.cpp
|
||||
GenericsBridging.cpp
|
||||
LangOptionsBridging.cpp
|
||||
MiscBridging.cpp
|
||||
PatternBridging.cpp
|
||||
PluginBridging.cpp
|
||||
|
||||
@@ -180,7 +180,7 @@ target_link_libraries(swiftAST
|
||||
|
||||
if (SWIFT_BUILD_SWIFT_SYNTAX)
|
||||
target_link_libraries(swiftAST
|
||||
PRIVATE swiftASTGen)
|
||||
PRIVATE swiftASTGen swiftBasicSwift)
|
||||
endif()
|
||||
|
||||
set_swift_llvm_is_available(swiftAST)
|
||||
|
||||
@@ -126,21 +126,6 @@ extension BridgedLabeledStmtInfo: /*@retroactive*/ Swift.ExpressibleByNilLiteral
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
init(bridged: BridgedStringRef) {
|
||||
self.init(
|
||||
decoding: UnsafeBufferPointer(start: bridged.data, count: bridged.count),
|
||||
as: UTF8.self
|
||||
)
|
||||
}
|
||||
|
||||
public mutating func withBridgedString<R>(_ body: (BridgedStringRef) throws -> R) rethrows -> R {
|
||||
try withUTF8 { buffer in
|
||||
try body(BridgedStringRef(data: buffer.baseAddress, count: buffer.count))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SyntaxText {
|
||||
var bridged: BridgedStringRef {
|
||||
BridgedStringRef(data: self.baseAddress, count: self.count)
|
||||
|
||||
@@ -20,7 +20,6 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP
|
||||
Regex.swift
|
||||
SourceFile.swift
|
||||
StableHasher.swift
|
||||
StaticBuildConfiguration+ASTContext.swift
|
||||
Stmts.swift
|
||||
TypeAttrs.swift
|
||||
Types.swift
|
||||
@@ -38,4 +37,5 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP
|
||||
_CompilerSwiftParser
|
||||
_CompilerSwiftParserDiagnostics
|
||||
_CompilerSwiftDiagnostics
|
||||
swiftBasicSwift
|
||||
)
|
||||
|
||||
@@ -10,12 +10,23 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import BasicBridging
|
||||
import ASTBridging
|
||||
import swiftBasicSwift
|
||||
import SwiftDiagnostics
|
||||
@_spi(Compiler) import SwiftIfConfig
|
||||
@_spi(ExperimentalLanguageFeatures) import SwiftParser
|
||||
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
|
||||
|
||||
extension BridgedASTContext {
|
||||
/// Retrieve the (cached) static build configuration for this ASTContext.
|
||||
public var staticBuildConfiguration: StaticBuildConfiguration {
|
||||
staticBuildConfigurationPtr.assumingMemoryBound(
|
||||
to: StaticBuildConfiguration.self
|
||||
).pointee
|
||||
}
|
||||
}
|
||||
|
||||
/// A build configuration that uses the compiler's ASTContext to answer
|
||||
/// queries.
|
||||
struct CompilerBuildConfiguration: BuildConfiguration {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import ASTBridging
|
||||
import swiftBasicSwift
|
||||
import SwiftDiagnostics
|
||||
@_spi(Compiler) import SwiftParser
|
||||
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax
|
||||
|
||||
11
lib/ASTGen/Sources/BasicSwift/CMakeLists.txt
Normal file
11
lib/ASTGen/Sources/BasicSwift/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
add_pure_swift_host_library(swiftBasicSwift STATIC CXX_INTEROP
|
||||
StaticBuildConfiguration+LangOptions.swift
|
||||
String+BridgedString.swift
|
||||
|
||||
DEPENDENCIES
|
||||
swiftBasic
|
||||
SWIFT_DEPENDENCIES
|
||||
_CompilerSwiftCompilerPluginMessageHandling
|
||||
_CompilerSwiftSyntax
|
||||
_CompilerSwiftIfConfig
|
||||
)
|
||||
@@ -131,3 +131,19 @@ public func printStaticBuildConfiguration(
|
||||
|
||||
return result ?? BridgedStringRef()
|
||||
}
|
||||
|
||||
@_cdecl("swift_Basic_createStaticBuildConfiguration")
|
||||
public func createStaticBuildConfiguration(
|
||||
cLangOpts: BridgedLangOptions
|
||||
) -> UnsafeMutableRawPointer {
|
||||
let storage = UnsafeMutablePointer<StaticBuildConfiguration>.allocate(capacity: 1)
|
||||
storage.initialize(to: StaticBuildConfiguration(langOptions: cLangOpts))
|
||||
return UnsafeMutableRawPointer(storage)
|
||||
}
|
||||
|
||||
/// Free the given static build configuration.
|
||||
@_cdecl("swift_Basic_freeStaticBuildConfiguration")
|
||||
public func freeStaticBuildConfiguration(pointer: UnsafeMutableRawPointer) {
|
||||
pointer.assumingMemoryBound(to: StaticBuildConfiguration.self)
|
||||
.deinitialize(count: 1).deallocate()
|
||||
}
|
||||
28
lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift
Normal file
28
lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift
Normal file
@@ -0,0 +1,28 @@
|
||||
//===--- String+BridgedString.swift ---------------------------------------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import BasicBridging
|
||||
|
||||
extension String {
|
||||
public init(bridged: BridgedStringRef) {
|
||||
self.init(
|
||||
decoding: UnsafeBufferPointer(start: bridged.data, count: bridged.count),
|
||||
as: UTF8.self
|
||||
)
|
||||
}
|
||||
|
||||
public mutating func withBridgedString<R>(_ body: (BridgedStringRef) throws -> R) rethrows -> R {
|
||||
try withUTF8 { buffer in
|
||||
try body(BridgedStringRef(data: buffer.baseAddress, count: buffer.count))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
add_subdirectory(BasicSwift)
|
||||
add_subdirectory(ASTGen)
|
||||
add_subdirectory(MacroEvaluation)
|
||||
add_subdirectory(SwiftIDEUtilsBridging)
|
||||
|
||||
@@ -14,6 +14,7 @@ import ASTBridging
|
||||
import BasicBridging
|
||||
@_spi(PluginMessage) @_spi(ExperimentalLanguageFeature) import SwiftCompilerPluginMessageHandling
|
||||
import SwiftDiagnostics
|
||||
import SwiftIfConfig
|
||||
import SwiftParser
|
||||
import SwiftSyntax
|
||||
@_spi(ExperimentalLanguageFeature) @_spi(Compiler) import SwiftSyntaxMacroExpansion
|
||||
@@ -419,7 +420,7 @@ func makeExpansionOutputResult(
|
||||
@_cdecl("swift_Macros_expandFreestandingMacro")
|
||||
@usableFromInline
|
||||
func expandFreestandingMacro(
|
||||
diagEnginePtr: UnsafeMutableRawPointer,
|
||||
cContext: BridgedASTContext,
|
||||
macroPtr: UnsafeRawPointer,
|
||||
discriminatorText: UnsafePointer<CChar>,
|
||||
rawMacroRole: UInt8,
|
||||
@@ -461,7 +462,7 @@ func expandFreestandingMacro(
|
||||
let expandedSource: String? = expandFreestandingMacroImpl(
|
||||
macroPtr: macroPtr,
|
||||
macroRole: macroRole,
|
||||
diagEnginePtr: diagEnginePtr,
|
||||
cContext: cContext,
|
||||
expansionSyntax: expansion,
|
||||
sourceFilePtr: sourceFilePtr,
|
||||
discriminator: discriminator
|
||||
@@ -476,7 +477,7 @@ func expandFreestandingMacro(
|
||||
func expandFreestandingMacroImpl(
|
||||
macroPtr: UnsafeRawPointer,
|
||||
macroRole: MacroRole,
|
||||
diagEnginePtr: UnsafeMutableRawPointer,
|
||||
cContext: BridgedASTContext,
|
||||
expansionSyntax: FreestandingMacroExpansionSyntax,
|
||||
sourceFilePtr: UnsafePointer<ExportedSourceFile>,
|
||||
discriminator: String
|
||||
@@ -505,14 +506,15 @@ func expandFreestandingMacroImpl(
|
||||
}
|
||||
|
||||
// Send the message.
|
||||
let message = HostToPluginMessage.expandFreestandingMacro(
|
||||
macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName),
|
||||
macroRole: pluginMacroRole,
|
||||
discriminator: discriminator,
|
||||
syntax: PluginMessage.Syntax(syntax: Syntax(expansionSyntax), in: sourceFilePtr)!,
|
||||
lexicalContext: pluginLexicalContext(of: expansionSyntax)
|
||||
)
|
||||
do {
|
||||
let message = HostToPluginMessage.expandFreestandingMacro(
|
||||
macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName),
|
||||
macroRole: pluginMacroRole,
|
||||
discriminator: discriminator,
|
||||
syntax: PluginMessage.Syntax(syntax: Syntax(expansionSyntax), in: sourceFilePtr)!,
|
||||
lexicalContext: pluginLexicalContext(of: expansionSyntax),
|
||||
staticBuildConfiguration: try cContext.staticBuildConfiguration.asJSON
|
||||
)
|
||||
let result = try macro.plugin.sendMessageAndWait(message)
|
||||
let expandedSource: String?
|
||||
let diagnostics: [PluginMessage.Diagnostic]
|
||||
@@ -527,14 +529,14 @@ func expandFreestandingMacroImpl(
|
||||
|
||||
// Process the result.
|
||||
if !diagnostics.isEmpty {
|
||||
let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: diagEnginePtr)
|
||||
let diagEngine = PluginDiagnosticsEngine(cContext: cContext)
|
||||
diagEngine.add(exportedSourceFile: sourceFilePtr)
|
||||
diagEngine.emit(diagnostics, messageSuffix: " (from macro '\(macroName)')")
|
||||
}
|
||||
return expandedSource
|
||||
|
||||
} catch let error {
|
||||
let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
|
||||
let srcMgr = SourceManager(cContext: cContext)
|
||||
srcMgr.insert(sourceFilePtr)
|
||||
srcMgr.diagnose(
|
||||
diagnostic: .init(
|
||||
@@ -552,7 +554,7 @@ func expandFreestandingMacroImpl(
|
||||
@_cdecl("swift_Macros_expandAttachedMacro")
|
||||
@usableFromInline
|
||||
func expandAttachedMacro(
|
||||
diagEnginePtr: UnsafeMutableRawPointer,
|
||||
cContext: BridgedASTContext,
|
||||
macroPtr: UnsafeRawPointer,
|
||||
discriminatorText: UnsafePointer<CChar>,
|
||||
qualifiedTypeText: UnsafePointer<CChar>,
|
||||
@@ -610,7 +612,7 @@ func expandAttachedMacro(
|
||||
let conformanceList = String(cString: conformanceListText)
|
||||
|
||||
let expandedSource: String? = expandAttachedMacroImpl(
|
||||
diagEnginePtr: diagEnginePtr,
|
||||
cContext: cContext,
|
||||
macroPtr: macroPtr,
|
||||
rawMacroRole: rawMacroRole,
|
||||
discriminator: discriminator,
|
||||
@@ -645,7 +647,7 @@ private func pluginLexicalContext(of node: some SyntaxProtocol) -> [PluginMessag
|
||||
}
|
||||
|
||||
func expandAttachedMacroImpl(
|
||||
diagEnginePtr: UnsafeMutableRawPointer,
|
||||
cContext: BridgedASTContext,
|
||||
macroPtr: UnsafeRawPointer,
|
||||
rawMacroRole: UInt8,
|
||||
discriminator: String,
|
||||
@@ -718,18 +720,19 @@ func expandAttachedMacroImpl(
|
||||
|
||||
|
||||
// Send the message.
|
||||
let message = HostToPluginMessage.expandAttachedMacro(
|
||||
macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName),
|
||||
macroRole: macroRole,
|
||||
discriminator: discriminator,
|
||||
attributeSyntax: customAttributeSyntax,
|
||||
declSyntax: declSyntax,
|
||||
parentDeclSyntax: parentDeclSyntax,
|
||||
extendedTypeSyntax: extendedTypeSyntax,
|
||||
conformanceListSyntax: conformanceListSyntax,
|
||||
lexicalContext: pluginLexicalContext(of: declarationNode)
|
||||
)
|
||||
do {
|
||||
let message = HostToPluginMessage.expandAttachedMacro(
|
||||
macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName),
|
||||
macroRole: macroRole,
|
||||
discriminator: discriminator,
|
||||
attributeSyntax: customAttributeSyntax,
|
||||
declSyntax: declSyntax,
|
||||
parentDeclSyntax: parentDeclSyntax,
|
||||
extendedTypeSyntax: extendedTypeSyntax,
|
||||
conformanceListSyntax: conformanceListSyntax,
|
||||
lexicalContext: pluginLexicalContext(of: declarationNode),
|
||||
staticBuildConfiguration: try cContext.staticBuildConfiguration.asJSON
|
||||
)
|
||||
let expandedSource: String?
|
||||
let diagnostics: [PluginMessage.Diagnostic]
|
||||
switch try macro.plugin.sendMessageAndWait(message) {
|
||||
@@ -756,7 +759,7 @@ func expandAttachedMacroImpl(
|
||||
|
||||
// Process the result.
|
||||
if !diagnostics.isEmpty {
|
||||
let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: diagEnginePtr)
|
||||
let diagEngine = PluginDiagnosticsEngine(cContext: cContext)
|
||||
diagEngine.add(exportedSourceFile: customAttrSourceFilePtr)
|
||||
diagEngine.add(exportedSourceFile: declarationSourceFilePtr)
|
||||
if let parentDeclSourceFilePtr = parentDeclSourceFilePtr {
|
||||
@@ -767,7 +770,7 @@ func expandAttachedMacroImpl(
|
||||
return expandedSource
|
||||
|
||||
} catch let error {
|
||||
let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
|
||||
let srcMgr = SourceManager(cContext: cContext)
|
||||
srcMgr.insert(customAttrSourceFilePtr)
|
||||
srcMgr.insert(declarationSourceFilePtr)
|
||||
if let parentDeclSourceFilePtr = parentDeclSourceFilePtr {
|
||||
@@ -787,3 +790,11 @@ func expandAttachedMacroImpl(
|
||||
}
|
||||
}
|
||||
|
||||
extension StaticBuildConfiguration {
|
||||
/// Form the JSON representation of this static build configuration.
|
||||
var asJSON: String {
|
||||
get throws {
|
||||
try String(decoding: JSON.encode(self), as: UTF8.self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,8 +201,8 @@ class PluginDiagnosticsEngine {
|
||||
private let bridgedDiagEngine: BridgedDiagnosticEngine
|
||||
private var exportedSourceFileByName: [String: UnsafePointer<ExportedSourceFile>] = [:]
|
||||
|
||||
init(cxxDiagnosticEngine: UnsafeMutableRawPointer) {
|
||||
self.bridgedDiagEngine = BridgedDiagnosticEngine(raw: cxxDiagnosticEngine)
|
||||
init(cContext: BridgedASTContext) {
|
||||
self.bridgedDiagEngine = cContext.diags
|
||||
}
|
||||
|
||||
/// Failable convenience initializer for optional cxx engine pointer.
|
||||
|
||||
@@ -23,6 +23,10 @@ class SourceManager {
|
||||
self.bridgedDiagEngine = BridgedDiagnosticEngine(raw: cxxDiagnosticEngine)
|
||||
}
|
||||
|
||||
init(cContext: BridgedASTContext) {
|
||||
self.bridgedDiagEngine = cContext.diags
|
||||
}
|
||||
|
||||
/// The bridged diagnostic engine (just the wrapped C++ `DiagnosticEngine`).
|
||||
let bridgedDiagEngine: BridgedDiagnosticEngine
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ add_swift_host_library(swiftBasic STATIC
|
||||
ParseableOutput.cpp
|
||||
JSONSerialization.cpp
|
||||
LangOptions.cpp
|
||||
LangOptionsBridging.cpp
|
||||
LoadDynamicLibrary.cpp
|
||||
Located.cpp
|
||||
Mangler.cpp
|
||||
|
||||
@@ -37,11 +37,6 @@ bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts,
|
||||
return cLangOpts.unbridged().hasFeature(cName.unbridged());
|
||||
}
|
||||
|
||||
bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName) {
|
||||
return hasAttribute(cLangOpts.unbridged(), cName.unbridged());
|
||||
}
|
||||
|
||||
bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts,
|
||||
BridgedStringRef cName) {
|
||||
return cLangOpts.unbridged().checkPlatformCondition(
|
||||
@@ -121,6 +116,90 @@ SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(
|
||||
cElements);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// Describe behaviors that should prevent an attribute from being shown.
|
||||
///
|
||||
/// This is DeclAttrBehaviors, but with irrelevent values set to zero.
|
||||
enum DeclAttrBehaviorsNotShown : uint64_t {
|
||||
/// Whether this attribute is only valid when concurrency is enabled.
|
||||
ConcurrencyOnly = 0,
|
||||
|
||||
/// True if multiple instances of this attribute are allowed on a single
|
||||
/// declaration.
|
||||
AllowMultipleAttributes = 0,
|
||||
|
||||
/// True if this is a decl modifier - i.e., that it should not be spelled
|
||||
/// with an @.
|
||||
DeclModifier = 1ull << 2,
|
||||
|
||||
/// True if this is a long attribute that should be printed on its own line.
|
||||
///
|
||||
/// Currently has no effect on DeclModifier attributes.
|
||||
LongAttribute = 0,
|
||||
|
||||
/// True if this shouldn't be serialized.
|
||||
NotSerialized = 0,
|
||||
|
||||
/// True if this attribute is only valid when parsing a .sil file.
|
||||
SILOnly = 1ull << 5,
|
||||
|
||||
/// The attribute should be reported by parser as unknown.
|
||||
RejectByParser = 1ull << 6,
|
||||
|
||||
/// Whether client code cannot use the attribute. Hides it in code completion.
|
||||
UserInaccessible = 1ull << 7,
|
||||
|
||||
/// Whether adding this attribute can break API
|
||||
APIBreakingToAdd = 0,
|
||||
|
||||
/// Whether removing this attribute can break API
|
||||
APIBreakingToRemove = 0,
|
||||
|
||||
/// Whether adding this attribute can break ABI
|
||||
ABIBreakingToAdd = 0,
|
||||
|
||||
/// Whether removing this attribute can break ABI
|
||||
ABIBreakingToRemove = 0,
|
||||
|
||||
/// The opposite of APIBreakingToAdd
|
||||
APIStableToAdd = 0,
|
||||
|
||||
/// The opposite of APIBreakingToRemove
|
||||
APIStableToRemove = 0,
|
||||
|
||||
/// The opposite of ABIBreakingToAdd
|
||||
ABIStableToAdd = 0,
|
||||
|
||||
/// The opposite of ABIBreakingToRemove
|
||||
ABIStableToRemove = 0,
|
||||
|
||||
/// Attribute should not be used in an \c \@abi attribute. Use for
|
||||
/// attributes which cannot affect mangled names, even indirectly, and
|
||||
/// which either don't affect ABI or where ABI-only declarations get their
|
||||
/// behavior from their API counterpart.
|
||||
ForbiddenInABIAttr = 0,
|
||||
|
||||
/// Attribute can be used without restrictions in an \c \@abi attribute.
|
||||
/// Use for attributes which affect mangled names but otherwise don't alter
|
||||
/// the ABI, or ones where the \c ABIDeclChecker manually implements
|
||||
/// special checking logic (e.g. because several different attributes
|
||||
/// contribute to the same aspect of ABI in some complicated way).
|
||||
UnconstrainedInABIAttr = 0,
|
||||
|
||||
/// Attribute can be used in an \c \@abi attribute, but must match
|
||||
/// equivalent on API decl. Use for attributes which affect both mangled
|
||||
/// names and other parts of the ABI such that the declaration can only be
|
||||
/// valid if they match.
|
||||
EquivalentInABIAttr = 0,
|
||||
|
||||
/// Use for attributes which are \em only valid on declarations that cannot
|
||||
/// have an \c @abi attribute, such as \c ImportDecl .
|
||||
UnreachableInABIAttr = 0,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void BridgedLangOptions_enumerateBuildConfigurationEntries(
|
||||
BridgedLangOptions cLangOpts,
|
||||
void * _Nonnull callbackContext,
|
||||
@@ -143,13 +222,13 @@ void BridgedLangOptions_enumerateBuildConfigurationEntries(
|
||||
|
||||
// Enumerate attributes that are available.
|
||||
#define DECL_ATTR(SPELLING, CLASS, REQUIREMENTS, BEHAVIORS, CODE) \
|
||||
if (hasAttribute(langOpts, #SPELLING)) \
|
||||
if ((BEHAVIORS) == 0) \
|
||||
callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING));
|
||||
#include "swift/AST/DeclAttr.def"
|
||||
|
||||
#define SIL_TYPE_ATTR(X, C)
|
||||
#define TYPE_ATTR(SPELLING, CLASS) \
|
||||
if (hasAttribute(langOpts, #SPELLING)) \
|
||||
callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING));
|
||||
callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING));
|
||||
#include "swift/AST/TypeAttr.def"
|
||||
|
||||
// Deal with all of the target platform/architecture information.
|
||||
@@ -1217,7 +1217,7 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion,
|
||||
BridgedStringRef evaluatedSourceOut{nullptr, 0};
|
||||
assert(!externalDef.isError());
|
||||
swift_Macros_expandFreestandingMacro(
|
||||
&ctx.Diags, externalDef.get(), discriminator->c_str(),
|
||||
ctx, externalDef.get(), discriminator->c_str(),
|
||||
getRawMacroRole(macroRole), astGenSourceFile,
|
||||
expansion->getSourceRange().Start.getOpaquePointerValue(),
|
||||
&evaluatedSourceOut);
|
||||
@@ -1574,7 +1574,7 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo,
|
||||
BridgedStringRef evaluatedSourceOut{nullptr, 0};
|
||||
assert(!externalDef.isError());
|
||||
swift_Macros_expandAttachedMacro(
|
||||
&ctx.Diags, externalDef.get(), discriminator->c_str(),
|
||||
ctx, externalDef.get(), discriminator->c_str(),
|
||||
extendedType.c_str(), conformanceList.c_str(), getRawMacroRole(role),
|
||||
astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(),
|
||||
astGenDeclSourceFile, startLoc.getOpaquePointerValue(),
|
||||
@@ -1717,7 +1717,7 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro,
|
||||
BridgedStringRef evaluatedSourceOut{nullptr, 0};
|
||||
assert(!externalDef.isError());
|
||||
swift_Macros_expandAttachedMacro(
|
||||
&ctx.Diags, externalDef.get(), discriminator->c_str(),
|
||||
ctx, externalDef.get(), discriminator->c_str(),
|
||||
"", "", getRawMacroRole(role),
|
||||
astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(),
|
||||
astGenClosureSourceFile, startLoc.getOpaquePointerValue(),
|
||||
|
||||
@@ -2980,3 +2980,21 @@ public struct BigEndianAccessorMacro: AccessorMacro {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
public struct CustomConditionCheckMacro: ExpressionMacro {
|
||||
public static func expansion(
|
||||
of node: some FreestandingMacroExpansionSyntax,
|
||||
in context: some MacroExpansionContext
|
||||
) throws -> ExprSyntax {
|
||||
guard let firstElement = node.arguments.first,
|
||||
let stringLiteral = firstElement.expression
|
||||
.as(StringLiteralExprSyntax.self),
|
||||
stringLiteral.segments.count == 1,
|
||||
case let .stringSegment(conditionName)? = stringLiteral.segments.first else {
|
||||
throw CustomError.message("macro requires a string literal containing the name of a custom condition")
|
||||
}
|
||||
|
||||
let isSet = try context.buildConfiguration?.isCustomConditionSet(name: conditionName.content.text) ?? false
|
||||
return "\(literal: isSet)"
|
||||
}
|
||||
}
|
||||
|
||||
17
test/Macros/macro_build_config.swift
Normal file
17
test/Macros/macro_build_config.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
// REQUIRES: swift_swift_parser, executable_test
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift
|
||||
|
||||
// Execution testing
|
||||
// RUN: %target-build-swift -swift-version 5 -g -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -Xfrontend -emit-dependencies-path -Xfrontend %t/main.d -Xfrontend -emit-reference-dependencies-path -Xfrontend %t/main.swiftdeps -DDEBUG
|
||||
// RUN: %target-codesign %t/main
|
||||
// RUN: %target-run %t/main | %FileCheck %s
|
||||
|
||||
@freestanding(expression) macro isCustomConditionSet(_ name: String) -> Bool = #externalMacro(module: "MacroDefinition", type: "CustomConditionCheckMacro")
|
||||
|
||||
// CHECK: Release = false
|
||||
print("Release = \(#isCustomConditionSet("RELEASE"))")
|
||||
|
||||
// CHECK: Debug = true
|
||||
print("Debug = \(#isCustomConditionSet("DEBUG"))")
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
// CHECK: ->(plugin:[[#PID:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}}
|
||||
// CHECK: <-(plugin:[[#PID]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}}
|
||||
// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}func test{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}}
|
||||
// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}func test{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}}
|
||||
// CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"\"123\"\n + \"foo \""}}
|
||||
// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}}
|
||||
// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}}
|
||||
// CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[],"message":"message from plugin","notes":[],"position":{"fileName":"{{.*}}test.swift","offset":336},"severity":"error"}],"expandedSource":"\"bar\""}}
|
||||
|
||||
//--- test.swift
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
// CHECK: ->(plugin:[[#PID1:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":7,"offset":[[#]]},"source":"#fooMacro(1)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":7,"offset":[[#]]},"source":"#fooMacro(1)"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"invalidResponse":{}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":9,"offset":[[#]]},"source":"#fooMacro(2)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":9,"offset":[[#]]},"source":"#fooMacro(2)"}}}
|
||||
// ^ This messages causes the mock plugin exit because there's no matching expected message.
|
||||
|
||||
// CHECK: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":11,"offset":[[#]]},"source":"#fooMacro(3)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":11,"offset":[[#]]},"source":"#fooMacro(3)"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2:]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"3.description"}}
|
||||
|
||||
//--- test.swift
|
||||
|
||||
@@ -71,9 +71,9 @@
|
||||
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID1]]) {"expandMacroResult":{"diagnostics":[],"expandedSource":"(a + b, \"a + b\")"}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}}
|
||||
// ^ This crashes the plugin server.
|
||||
|
||||
// CHECK: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}}
|
||||
@@ -82,12 +82,12 @@
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[],"expandedSource":"(b + a, \"b + a\")"}}
|
||||
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"missing","typeName":"TypeDoesNotExist"},"macroRole":"expression","syntax":{"kind":"expression","location":{{({.+})}},"source":"#missing()"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"missing","typeName":"TypeDoesNotExist"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{({.+})}},"source":"#missing()"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[{{{.*}}}],"message":"type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '{{.*}}MacroDefinition.{{dylib|so|dll}}'","notes":[],"position":{{{.*}}},"severity":"error"}]}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"notMacro","typeName":"NotMacroStruct"},"macroRole":"expression","syntax":{"kind":"expression","location":{{({.+})}},"source":"#notMacro()"}}}
|
||||
// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"notMacro","typeName":"NotMacroStruct"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{({.+})}},"source":"#notMacro()"}}}
|
||||
// CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[{{{.*}}}],"message":"type 'MacroDefinition.NotMacroStruct' is not a valid macro implementation type in library plugin '{{.*}}MacroDefinition.{{dylib|so|dll}}'","notes":[],"position":{{{.*}}},"severity":"error"}]}}
|
||||
|
||||
@freestanding(expression) macro stringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro")
|
||||
|
||||
Reference in New Issue
Block a user