Skip to content

Instantly share code, notes, and snippets.

@sujinnaljin
Created July 1, 2023 07:36
Show Gist options
  • Save sujinnaljin/cbbf3269a2a8eb8a8e97b7b3163d6251 to your computer and use it in GitHub Desktop.
Save sujinnaljin/cbbf3269a2a8eb8a8e97b7b3163d6251 to your computer and use it in GitHub Desktop.
DictionaryStorageMacro.swift
public struct DictionaryStorageMacro: MemberMacro {
public static func expansion(of node: AttributeSyntax,
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
let stringIdentifier = SimpleTypeIdentifierSyntax(name: .identifier("String"))
let anyIdentifier = SimpleTypeIdentifierSyntax(name: .keyword(.Any))
let dictionarySyntax = DictionaryTypeSyntax(leftSquareBracket: .leftSquareBracketToken(),
keyType: stringIdentifier,
colon: .colonToken(),
valueType: anyIdentifier,
rightSquareBracket: .rightSquareBracketToken())
let functionParameterSyntax = FunctionParameterSyntax(firstName: .identifier("dictionary"),
colon: .colonToken(),
type: dictionarySyntax)
let functionParameterListSyntax = FunctionParameterListSyntax([functionParameterSyntax])
let parameterClauseSyntax = ParameterClauseSyntax.init(leftParen: .leftParenToken(),
parameterList: functionParameterListSyntax,
rightParen: .rightParenToken())
let signature = FunctionSignatureSyntax.init(input: parameterClauseSyntax)
let codeBlockItemListSyntax = CodeBlockItemListSyntax.init {
let exprListSyntax = ExprListSyntax.init {
let selfIdentifier = IdentifierExprSyntax(identifier: .keyword(.self))
let memberAccessExprSyntax = MemberAccessExprSyntax(base: selfIdentifier,
dot: .periodToken(),
name: .identifier("dictionary"))
let assignmentExprSyntax = AssignmentExprSyntax(assignToken: .equalToken())
let identifierExprSyntax = IdentifierExprSyntax(identifier: .identifier("dictionary"))
return [memberAccessExprSyntax,
assignmentExprSyntax,
identifierExprSyntax]
}
let sequenceExprSyntax = SequenceExprSyntax.init(elements: exprListSyntax)
let codeBlockItemSyntaxItem = CodeBlockItemSyntax.Item.init(sequenceExprSyntax)
let codeBlockItemSyntax = CodeBlockItemSyntax.init(item: codeBlockItemSyntaxItem)
return [codeBlockItemSyntax]
}
let codeBlockSyntax = CodeBlockSyntax.init(leftBrace: .leftBraceToken(),
statements: codeBlockItemListSyntax,
rightBrace: .rightBraceToken())
let initializerDeclSyntax = InitializerDeclSyntax.init(initKeyword: .keyword(.`init`),
signature: signature,
body: codeBlockSyntax)
let patternBindingListSyntax = PatternBindingListSyntax.init {
let stringIdentifier = SimpleTypeIdentifierSyntax(name: .identifier("String"))
let anyIdentifier = SimpleTypeIdentifierSyntax(name: .keyword(.Any))
let dictionarySyntax = DictionaryTypeSyntax(leftSquareBracket: .leftSquareBracketToken(),
keyType: stringIdentifier,
colon: .colonToken(),
valueType: anyIdentifier,
rightSquareBracket: .rightSquareBracketToken())
let typeAnnotationSyntax = TypeAnnotationSyntax.init(colon: TokenSyntax.colonToken(),
type: dictionarySyntax)
let dictionaryIdentifier = IdentifierPatternSyntax.init(identifier: "dictionary")
let patternBindingSyntax = PatternBindingSyntax.init(pattern: dictionaryIdentifier,
typeAnnotation: typeAnnotationSyntax)
return [patternBindingSyntax]
}
let variableDeclSyntax = VariableDeclSyntax.init(bindingKeyword: .keyword(.var),
bindings: patternBindingListSyntax)
return [
DeclSyntax(initializerDeclSyntax),
DeclSyntax(variableDeclSyntax),
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment