Skip to content

[Macros] Replace all uses of the ConformanceMacro protocol with ExtensionMacro. #67762

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 1 commit into from
Aug 5, 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
30 changes: 14 additions & 16 deletions lib/Macros/Sources/SwiftMacros/OptionSetMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,27 +123,25 @@ public struct OptionSetMacro {
}
}

extension OptionSetMacro: ConformanceMacro {
public static func expansion<
Decl: DeclGroupSyntax,
Context: MacroExpansionContext
>(
extension OptionSetMacro: ExtensionMacro {
public static func expansion(
of attribute: AttributeSyntax,
providingConformancesOf decl: Decl,
in context: Context
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
// Decode the expansion arguments.
guard let (structDecl, _, _) = decodeExpansion(of: attribute, attachedTo: decl, in: context) else {
return []
}

attachedTo decl: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [ExtensionDeclSyntax] {
// If there is an explicit conformance to OptionSet already, don't add one.
if let inheritedTypes = structDecl.inheritanceClause?.inheritedTypes,
inheritedTypes.contains(where: { inherited in inherited.type.trimmedDescription == "OptionSet" }) {
if protocols.isEmpty {
return []
}

return [("OptionSet", nil)]
let ext: DeclSyntax =
"""
extension \(type.trimmed): OptionSet {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we/should we trim the type before passing it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't recall whether we do (I copied this from elsewhere), but we should if we don't already

"""

return [ext.cast(ExtensionDeclSyntax.self)]
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we should make ExtensionDeclSyntax SyntaxParseable.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes please!

}
}

Expand Down
12 changes: 7 additions & 5 deletions test/Index/index_macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,16 @@ public struct SomeAccessorMacro: AccessorMacro {
}
}

public struct SomeConformanceMacro: ConformanceMacro {
public struct SomeConformanceMacro: ExtensionMacro {
public static func expansion(
of node: AttributeSyntax,
providingConformancesOf decl: some DeclGroupSyntax,
attachedTo: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
let protocolName: TypeSyntax = "TestProto"
return [(protocolName, nil)]
) throws -> [ExtensionDeclSyntax] {
let ext: DeclSyntax = "extension \(type.trimmed): TestProto {}"
return [ext.cast(ExtensionDeclSyntax.self)]
}
}

Expand Down
62 changes: 31 additions & 31 deletions test/Macros/Inputs/syntax_macro_definitions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1281,14 +1281,16 @@ public struct EmptyPeerMacro: PeerMacro {
}
}

public struct EquatableMacro: ConformanceMacro {
public struct EquatableMacro: ExtensionMacro {
public static func expansion(
of node: AttributeSyntax,
providingConformancesOf decl: some DeclGroupSyntax,
attachedTo: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
let protocolName: TypeSyntax = "Equatable"
return [(protocolName, nil)]
) throws -> [ExtensionDeclSyntax] {
let ext: DeclSyntax = "extension \(type.trimmed): Equatable {}"
return [ext.cast(ExtensionDeclSyntax.self)]
}
}

Expand Down Expand Up @@ -1316,34 +1318,37 @@ public struct ConformanceViaExtensionMacro: ExtensionMacro {
}
}

public struct HashableMacro: ConformanceMacro {
public struct HashableMacro: ExtensionMacro {
public static func expansion(
of node: AttributeSyntax,
providingConformancesOf decl: some DeclGroupSyntax,
attachedTo: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
let protocolName: TypeSyntax = "Hashable"
return [(protocolName, nil)]
) throws -> [ExtensionDeclSyntax] {
let ext: DeclSyntax = "extension \(type.trimmed): Hashable {}"
return [ext.cast(ExtensionDeclSyntax.self)]
}
}

public struct DelegatedConformanceMacro: ConformanceMacro, MemberMacro {
public struct DelegatedConformanceMacro: ExtensionMacro, MemberMacro {
public static func expansion(
of node: AttributeSyntax,
providingConformancesOf decl: some DeclGroupSyntax,
attachedTo: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
let protocolName: TypeSyntax = "P"
) throws -> [ExtensionDeclSyntax] {
let conformance: DeclSyntax =
"""
extension Placeholder where Element: P {}
extension \(type.trimmed): P where Element: P {}
"""

guard let extensionDecl = conformance.as(ExtensionDeclSyntax.self) else {
return []
}

return [(protocolName, extensionDecl.genericWhereClause)]
return [extensionDecl]
}

public static func expansion(
Expand Down Expand Up @@ -1760,26 +1765,21 @@ public struct AddPeerStoredPropertyMacro: PeerMacro, Sendable {
}
}

public struct InitializableMacro: ConformanceMacro, MemberMacro {
public struct InitializableMacro: ExtensionMacro {
public static func expansion(
of node: AttributeSyntax,
providingConformancesOf decl: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
return [("Initializable", nil)]
}

public static func expansion(
of node: AttributeSyntax,
providingMembersOf decl: some DeclGroupSyntax,
attachedTo: some DeclGroupSyntax,
providingExtensionsOf type: some TypeSyntaxProtocol,
conformingTo protocols: [TypeSyntax],
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
let requirement: DeclSyntax =
) throws -> [ExtensionDeclSyntax] {
let ext: DeclSyntax =
"""
init(value: Int) {}
extension \(type.trimmed): Initializable {
init(value: Int) {}
}
"""

return [requirement]
return [ext.cast(ExtensionDeclSyntax.self)]
}
}

Expand Down
3 changes: 1 addition & 2 deletions test/Macros/top_level_freestanding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ macro Empty<T>(_ closure: () -> T) = #externalMacro(module: "MacroDefinition", t
S(a: 10, b: 10)
}

@attached(extension, conformances: Initializable)
@attached(member, names: named(init))
@attached(extension, conformances: Initializable, names: named(init))
macro Initializable() = #externalMacro(module: "MacroDefinition", type: "InitializableMacro")

protocol Initializable {
Expand Down