Skip to content

Commit

Permalink
Allow key name to be customized
Browse files Browse the repository at this point in the history
  • Loading branch information
emorydunn committed Jan 27, 2025
1 parent 8e81093 commit ba73529
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Sources/StreamDeck/Macros/SettingsMacros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public macro globalSetting<T>(_ name: String, defaultValue value: T, ofType: T.T
public macro environmentKey<T>(_ name: String, defaultValue value: T, ofType: T.Type) = #externalMacro(module: "StreamDeckMacros", type: "EnvironmentMacro")

@attached(accessor)
@attached(peer, names: prefixed(__Key_))
public macro Entry() = #externalMacro(module: "StreamDeckMacros", type: "EntryMacro")
@attached(peer, names: arbitrary)
public macro Entry(_ name: String? = nil) = #externalMacro(module: "StreamDeckMacros", type: "EntryMacro")
#endif
34 changes: 30 additions & 4 deletions Sources/StreamDeckMacros/EntryMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ struct EntryMacro {
}
}

static func identifier(of node: AttributeSyntax, or declaration: some DeclSyntaxProtocol) throws -> String {
// Check if the user specified a custom name for the key
if let arg = customKeyName(for: node) {
return arg
} else {
return try identifier(of: declaration)
}
}

/// Return the identifier of a declaration.
static func identifier(of declaration: some DeclSyntaxProtocol) throws -> String {
guard let variableDecl = declaration.as(VariableDeclSyntax.self),
let patternBinding = variableDecl.bindings.as(PatternBindingListSyntax.self)?.first?.as(PatternBindingSyntax.self),
Expand All @@ -38,6 +48,7 @@ struct EntryMacro {
return identifier
}

/// Return the initializer of a declaration.
static func initializer(of declaration: some DeclSyntaxProtocol) throws -> InitializerClauseSyntax {
guard let variableDecl = declaration.as(VariableDeclSyntax.self),
let patternBinding = variableDecl.bindings.as(PatternBindingListSyntax.self)?.first?.as(PatternBindingSyntax.self),
Expand All @@ -50,6 +61,7 @@ struct EntryMacro {
return initializer
}

/// Return the type identifier the macro is in.
static func extensionKey(of context: some MacroExpansionContext) throws -> KeyType {
let extensionType = context.lexicalContext.first?
.as(ExtensionDeclSyntax.self)?.extendedType
Expand All @@ -65,14 +77,26 @@ struct EntryMacro {
return key

}

/// Return the string value of the first argument of a node.
static func customKeyName(for node: AttributeSyntax) -> String? {
guard
let exprList = node.arguments?.as(LabeledExprListSyntax.self),
let stringExpr = exprList.first?.expression.as(StringLiteralExprSyntax.self)
else {
return nil
}

return stringExpr.representedLiteralValue
}

}

extension EntryMacro: AccessorMacro {
static func expansion(of node: AttributeSyntax, providingAccessorsOf declaration: some DeclSyntaxProtocol, in context: some MacroExpansionContext
) throws -> [AccessorDeclSyntax] {

let identifier = try identifier(of: declaration)
let identifier = try identifier(of: node, or: declaration)

let settingName = "__Key_\(identifier)"

Expand All @@ -84,13 +108,15 @@ extension EntryMacro: AccessorMacro {
}

extension EntryMacro: PeerMacro {

static func expansion(of node: AttributeSyntax, providingPeersOf declaration: some DeclSyntaxProtocol, in context: some MacroExpansionContext) throws -> [DeclSyntax] {

let identifier = try identifier(of: declaration)
let keyIdentifier = try identifier(of: node, or: declaration)

let initializer = try initializer(of: declaration)
let keyType = try extensionKey(of: context)

let settingName = "__Key_\(identifier)"
let settingName = "__Key_\(keyIdentifier)"

// Create the inheritance token
let globSetKey = InheritanceClauseSyntax {
Expand All @@ -101,7 +127,7 @@ extension EntryMacro: PeerMacro {
let settingStruct = try StructDeclSyntax(name: "\(raw: settingName)") {

// Create an override for the key name
try VariableDeclSyntax("static let name = \"\(raw: settingName)\"")
try VariableDeclSyntax("static let name = \"\(raw: keyIdentifier)\"")

VariableDeclSyntax(bindingSpecifier: "static let") {
PatternBindingSyntax(
Expand Down

0 comments on commit ba73529

Please sign in to comment.