Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let experimentalFeaturesFile = SourceFileSyntax(leadingTrivia: copyrightHeader)
"""
extension Parser {
@_spi(ExperimentalLanguageFeatures)
public struct ExperimentalFeatures: OptionSet, Sendable {
public struct ExperimentalFeatures: OptionSet, Hashable, Sendable {
public let rawValue: UInt
public init(rawValue: UInt) {
self.rawValue = rawValue
Expand Down
10 changes: 8 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ let package = Package(

.target(
name: "SwiftIfConfig",
dependencies: ["SwiftSyntax", "SwiftSyntaxBuilder", "SwiftDiagnostics", "SwiftOperators"],
dependencies: ["SwiftSyntax", "SwiftSyntaxBuilder", "SwiftDiagnostics", "SwiftOperators", "SwiftParser"],
exclude: ["CMakeLists.txt"]
),

Expand Down Expand Up @@ -275,7 +275,13 @@ let package = Package(

.target(
name: "SwiftSyntaxMacros",
dependencies: ["SwiftDiagnostics", "SwiftParser", "SwiftSyntax", "SwiftSyntaxBuilder"],
dependencies: [
"SwiftDiagnostics",
"SwiftIfConfig",
"SwiftParser",
"SwiftSyntax",
"SwiftSyntaxBuilder",
],
exclude: ["CMakeLists.txt"]
),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ target_link_swift_syntax_libraries(SwiftCompilerPluginMessageHandling PUBLIC
SwiftSyntax
SwiftBasicFormat
SwiftDiagnostics
SwiftIfConfig
SwiftParser
SwiftSyntaxMacros
SwiftSyntaxMacroExpansion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import _SwiftSyntaxCShims
#endif

#if compiler(>=6)
internal import SwiftIfConfig
public import SwiftSyntaxMacros
#else
import SwiftIfConfig
import SwiftSyntaxMacros
#endif

Expand Down Expand Up @@ -189,12 +191,25 @@ public class PluginProviderMessageHandler<Provider: PluginProvider>: PluginMessa
let macroRole,
let discriminator,
let expandingSyntax,
let lexicalContext
let lexicalContext,
let staticBuildConfigurationString
):
// Decode the static build configuration.
let staticBuildConfiguration: StaticBuildConfiguration?
if let staticBuildConfigurationString {
var mutableConfigurationString = staticBuildConfigurationString
staticBuildConfiguration = mutableConfigurationString.withUTF8 {
try? JSON.decode(StaticBuildConfiguration.self, from: $0)
}
} else {
staticBuildConfiguration = nil
}

return expandFreestandingMacro(
macro: macro,
macroRole: macroRole,
discriminator: discriminator,
staticBuildConfiguration: staticBuildConfiguration,
expandingSyntax: expandingSyntax,
lexicalContext: lexicalContext
)
Expand All @@ -208,12 +223,25 @@ public class PluginProviderMessageHandler<Provider: PluginProvider>: PluginMessa
let parentDeclSyntax,
let extendedTypeSyntax,
let conformanceListSyntax,
let lexicalContext
let lexicalContext,
let staticBuildConfigurationString
):
// Decode the static build configuration.
let staticBuildConfiguration: StaticBuildConfiguration?
if let staticBuildConfigurationString {
var mutableConfigurationString = staticBuildConfigurationString
staticBuildConfiguration = mutableConfigurationString.withUTF8 {
try? JSON.decode(StaticBuildConfiguration.self, from: $0)
}
} else {
staticBuildConfiguration = nil
}

return expandAttachedMacro(
macro: macro,
macroRole: macroRole,
discriminator: discriminator,
staticBuildConfiguration: staticBuildConfiguration,
attributeSyntax: attributeSyntax,
declSyntax: declSyntax,
parentDeclSyntax: parentDeclSyntax,
Expand Down
62 changes: 50 additions & 12 deletions Sources/SwiftCompilerPluginMessageHandling/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@
#if compiler(>=6)
internal import SwiftBasicFormat
internal import SwiftDiagnostics
@_spi(ExperimentalLanguageFeatures) internal import SwiftIfConfig
internal import SwiftOperators
@_spi(ExperimentalLanguageFeatures) internal import SwiftParser
internal import SwiftSyntax
@_spi(MacroExpansion) @_spi(ExperimentalLanguageFeature) internal import SwiftSyntaxMacroExpansion
@_spi(ExperimentalLanguageFeature) internal import SwiftSyntaxMacros
#else
import SwiftBasicFormat
import SwiftDiagnostics
@_spi(ExperimentalLanguageFeatures) import SwiftIfConfig
import SwiftOperators
@_spi(ExperimentalLanguageFeatures) import SwiftParser
import SwiftSyntax
@_spi(MacroExpansion) @_spi(ExperimentalLanguageFeature) import SwiftSyntaxMacroExpansion
@_spi(ExperimentalLanguageFeature) import SwiftSyntaxMacros
Expand All @@ -36,6 +40,8 @@ extension PluginProviderMessageHandler {
private static func resolveLexicalContext(
_ lexicalContext: [PluginMessage.Syntax]?,
sourceManager: SourceManager,
swiftVersion: Parser.SwiftVersion?,
experimentalFeatures: Parser.ExperimentalFeatures?,
operatorTable: OperatorTable,
fallbackSyntax: some SyntaxProtocol
) -> [Syntax] {
Expand All @@ -45,29 +51,47 @@ extension PluginProviderMessageHandler {
return fallbackSyntax.allMacroLexicalContexts()
}

return lexicalContext.map { sourceManager.add($0, foldingWith: operatorTable) }
return lexicalContext.map {
sourceManager.add(
$0,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures,
foldingWith: operatorTable
)
}
}

/// Expand `@freestainding(XXX)` macros.
func expandFreestandingMacro(
macro: PluginMessage.MacroReference,
macroRole pluginMacroRole: PluginMessage.MacroRole?,
discriminator: String,
staticBuildConfiguration: StaticBuildConfiguration?,
expandingSyntax: PluginMessage.Syntax,
lexicalContext: [PluginMessage.Syntax]?
) -> PluginToHostMessage {
let sourceManager = SourceManager(syntaxRegistry: syntaxRegistry)
let syntax = sourceManager.add(expandingSyntax, foldingWith: .standardOperators)
let swiftVersion = staticBuildConfiguration?.parserSwiftVersion
let experimentalFeatures = staticBuildConfiguration?.experimentalFeatures
let syntax = sourceManager.add(
expandingSyntax,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures,
foldingWith: .standardOperators
)

let context = PluginMacroExpansionContext(
sourceManager: sourceManager,
lexicalContext: Self.resolveLexicalContext(
lexicalContext,
sourceManager: sourceManager,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures,
operatorTable: .standardOperators,
fallbackSyntax: syntax
),
expansionDiscriminator: discriminator
expansionDiscriminator: discriminator,
staticBuildConfiguration: staticBuildConfiguration
)

let expandedSource: String?
Expand Down Expand Up @@ -113,6 +137,7 @@ extension PluginProviderMessageHandler {
macro: PluginMessage.MacroReference,
macroRole: PluginMessage.MacroRole,
discriminator: String,
staticBuildConfiguration: StaticBuildConfiguration?,
attributeSyntax: PluginMessage.Syntax,
declSyntax: PluginMessage.Syntax,
parentDeclSyntax: PluginMessage.Syntax?,
Expand All @@ -121,17 +146,27 @@ extension PluginProviderMessageHandler {
lexicalContext: [PluginMessage.Syntax]?
) -> PluginToHostMessage {
let sourceManager = SourceManager(syntaxRegistry: syntaxRegistry)
let attributeNode = sourceManager.add(
attributeSyntax,
foldingWith: .standardOperators
).cast(AttributeSyntax.self)
let declarationNode = sourceManager.add(declSyntax)
let parentDeclNode = parentDeclSyntax.map { sourceManager.add($0).cast(DeclSyntax.self) }
let swiftVersion = staticBuildConfiguration?.parserSwiftVersion
let experimentalFeatures = staticBuildConfiguration?.experimentalFeatures

func addToSourceManager(_ syntax: PluginMessage.Syntax) -> Syntax {
sourceManager.add(
attributeSyntax,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures,
foldingWith: .standardOperators
)
}

let attributeNode = addToSourceManager(attributeSyntax)
.cast(AttributeSyntax.self)
let declarationNode = addToSourceManager(declSyntax)
let parentDeclNode = parentDeclSyntax.map { addToSourceManager($0).cast(DeclSyntax.self) }
let extendedType = extendedTypeSyntax.map {
sourceManager.add($0).cast(TypeSyntax.self)
addToSourceManager($0).cast(TypeSyntax.self)
}
let conformanceList = conformanceListSyntax.map {
let placeholderStruct = sourceManager.add($0).cast(StructDeclSyntax.self)
let placeholderStruct = addToSourceManager($0).cast(StructDeclSyntax.self)
return placeholderStruct.inheritanceClause!.inheritedTypes
}

Expand All @@ -140,10 +175,13 @@ extension PluginProviderMessageHandler {
lexicalContext: Self.resolveLexicalContext(
lexicalContext,
sourceManager: sourceManager,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures,
operatorTable: .standardOperators,
fallbackSyntax: declarationNode
),
expansionDiscriminator: discriminator
expansionDiscriminator: discriminator,
staticBuildConfiguration: staticBuildConfiguration
)

// TODO: Make this a 'String?' and remove non-'hasExpandMacroResult' branches.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@

#if compiler(>=6)
internal import SwiftDiagnostics
internal import SwiftIfConfig
internal import SwiftOperators
internal import SwiftParser
@_spi(ExperimentalLanguageFeatures) internal import SwiftParser
internal import SwiftSyntax
internal import SwiftSyntaxMacros
#else
import SwiftDiagnostics
import SwiftIfConfig
import SwiftOperators
import SwiftParser
@_spi(ExperimentalLanguageFeatures) import SwiftParser
import SwiftSyntax
import SwiftSyntaxMacros
#endif
Expand All @@ -29,6 +31,8 @@ class ParsedSyntaxRegistry {
struct Key: Hashable {
let source: String
let kind: PluginMessage.Syntax.Kind
let swiftVersion: Parser.SwiftVersion
let experimentalFeatures: Parser.ExperimentalFeatures
}

private var storage: LRUCache<Key, Syntax>
Expand All @@ -37,8 +41,17 @@ class ParsedSyntaxRegistry {
self.storage = LRUCache(capacity: cacheCapacity)
}

private func parse(source: String, kind: PluginMessage.Syntax.Kind) -> Syntax {
var parser = Parser(source)
private func parse(
source: String,
kind: PluginMessage.Syntax.Kind,
swiftVersion: Parser.SwiftVersion,
experimentalFeatures: Parser.ExperimentalFeatures
) -> Syntax {
var parser = Parser(
source,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures
)
switch kind {
case .declaration:
return Syntax(DeclSyntax.parse(from: &parser))
Expand All @@ -55,13 +68,30 @@ class ParsedSyntaxRegistry {
}
}

func get(source: String, kind: PluginMessage.Syntax.Kind) -> Syntax {
let key = Key(source: source, kind: kind)
func get(
source: String,
kind: PluginMessage.Syntax.Kind,
swiftVersion: Parser.SwiftVersion?,
experimentalFeatures: Parser.ExperimentalFeatures?
) -> Syntax {
let swiftVersion = swiftVersion ?? Parser.defaultSwiftVersion
let experimentalFeatures = experimentalFeatures ?? Parser.ExperimentalFeatures()
let key = Key(
source: source,
kind: kind,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures
)
if let cached = storage[key] {
return cached
}

let node = parse(source: source, kind: kind)
let node = parse(
source: source,
kind: kind,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures
)
storage[key] = node
return node
}
Expand Down Expand Up @@ -124,10 +154,16 @@ class SourceManager {
/// are cached in the source manager to provide `location(of:)` et al.
func add(
_ syntaxInfo: PluginMessage.Syntax,
foldingWith operatorTable: OperatorTable? = nil
swiftVersion: Parser.SwiftVersion?,
experimentalFeatures: Parser.ExperimentalFeatures?,
foldingWith operatorTable: OperatorTable?
) -> Syntax {

var node = syntaxRegistry.get(source: syntaxInfo.source, kind: syntaxInfo.kind)
var node = syntaxRegistry.get(
source: syntaxInfo.source,
kind: syntaxInfo.kind,
swiftVersion: swiftVersion,
experimentalFeatures: experimentalFeatures
)
if let operatorTable {
node = operatorTable.foldAll(node, errorHandler: { _ in /*ignore*/ })
}
Expand Down Expand Up @@ -262,6 +298,10 @@ class PluginMacroExpansionContext {
/// to produce unique names.
private var expansionDiscriminator: String

/// The static build configuration, if any, that will be used for the
/// macro-expanded code.
private var staticBuildConfiguration: StaticBuildConfiguration?

/// Counter for each of the uniqued names.
///
/// Used in conjunction with `expansionDiscriminator`.
Expand All @@ -271,10 +311,16 @@ class PluginMacroExpansionContext {
/// macro.
internal private(set) var diagnostics: [Diagnostic] = []

init(sourceManager: SourceManager, lexicalContext: [Syntax], expansionDiscriminator: String = "") {
init(
sourceManager: SourceManager,
lexicalContext: [Syntax],
expansionDiscriminator: String = "",
staticBuildConfiguration: StaticBuildConfiguration?
) {
self.sourceManager = sourceManager
self.lexicalContext = lexicalContext
self.expansionDiscriminator = expansionDiscriminator
self.staticBuildConfiguration = staticBuildConfiguration
}
}

Expand Down Expand Up @@ -321,4 +367,8 @@ extension PluginMacroExpansionContext: MacroExpansionContext {
}
return AbstractSourceLocation(location)
}

public var buildConfiguration: (any BuildConfiguration)? {
staticBuildConfiguration
}
}
Loading
Loading