Expand on Swift Macros


Why Macros

  • Lots of build in code expansion like Codable and property wrappers
  • Used to allow your own language features, to eliminate tedium and boiler plate.

Design Philosophy

  • Different from C Macros
  • Distinctive use sites
  • All start with either # or @ depending on type of macros
  • Complete, type-checked, validated – macros must be all of this
  • Inserted in a predictable additive ways.  It can not delete anything
  • Should not be  Magic – you can expand the macro in line or step into it in the debugger.  Even if it is a closed source library.

Translation Model

  • Basic concept,  extract the usage from code and sends to compiler plugin, in separate process and sandbox, and returns an expansion of code – which is added to your program – which is then compiled with your code.
  • All macros have to be declared so that the compiler can do the prior step – this is pacifically the API for the macro.  You can either import it via library/framework or write it inline in your code.
    • It must define it’s role

Macro Roles

  • Role is a set of rules for the macro
    • Where it can be used
    • What types of code it expands into
    • Where the expansions are inserted
  • They are responsible for achieving the goals.
Screenshot 2023-06-07 at 17.29.53 (2).png
  • There are two that create free standing macros and 5 that are attached macros
  • An expression is a piece of code that executes and presents a result.  
  • Detailed examples for each of these types of macros are gone thru in the session
  • If two different macros are attached to the same code it doesn’t matter about ordering, since they all are based on the original code.

Macro Implementation

  • Comes after an = sign, and it is always another macro
  • Usually an external macro implemented by a compiler plugin
  • #externalMacro specifies the plugin to call and use to expand the code.
  • You need to import SwiftSyntax – in your macro code to understand the Swift code syntax.  Check out the Write Swift Macros session or the SwiftSyntax developer documentation. 
  • Import SwiftSyntaxMacros – protocols and types
  • Import SwiftSyntaxBuilder – provides convince tools
  • You should include comprehensive error codes for when someone tries to use it incorrectly 
  • You can provide Fix buttons, highlights and other information in your error message when the macro is used incorrectly

Writing correct macros

  • Name collision – you can use the makeUniqueName() method on the macro expansion context.
  • ● Swift needs to use names outside of the macro, so you need to use makeUniqueName() to solve this.
Screenshot 2023-06-07 at 18.04.31 (2).png
  • Macros can only use the information that the compiler provides to them, so you can’t create a macro that inserts the current date and time (as an example)
  • Testing – it’s an ordinary swift module so you should write normal swift unit test for it
,