0Pricing
Swift Academy · レッスン

フリースタンディング式マクロの記述

SwiftSyntaxとMacroExpansionを使い、単純な#stringifyマクロを実装します。

「フリースタンディング式マクロの記述」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

プロジェクトのセットアップ

マクロは、SwiftSyntaxを使用する.macro種別の別のSwift packageターゲットに配置します。

// Package.swift (excerpt)
.macro(
  name: "MyMacros",
  dependencies: [
    .product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
    .product(name: "SwiftCompilerPlugin", package: "swift-syntax")
  ]
)

マクロの宣言

クライアントから呼び出せるように、ライブラリターゲットでマクロのシグネチャを宣言します。

@freestanding(expression)
public macro stringify<T>(_ value: T) -> (T, String)
  = #externalMacro(module: "MyMacros", type: "StringifyMacro")

マクロ型を実装する

ExpressionMacroに準拠し、ExprSyntaxを返すことでマクロを実装します。

import SwiftSyntaxMacros
import SwiftSyntax

struct StringifyMacro: ExpressionMacro {
  static func expansion(
    of node: some FreestandingMacroExpansionSyntax,
    in context: some MacroExpansionContext
  ) throws -> ExprSyntax {
    guard let arg = node.arguments.first?.expression else {
      throw MacroError.message("Need an argument")
    }
    return "(\(arg), \(literal: arg.description))"
  }
}

プラグインを登録する

パッケージ内のすべてのマクロを列挙するCompilerPluginを作成します。

import SwiftCompilerPlugin

@main
struct MyPlugin: CompilerPlugin {
  let providingMacros: [Macro.Type] = [
    StringifyMacro.self
  ]
}

マクロを使用する

マクロライブラリをインポートし、#stringifyで呼び出します。

import MyMacros
let (value, source) = #stringify(2 + 3)
print(value)   // 5
print(source)  // "2 + 3"

ExprSyntaxを構築する

戻り値はExprSyntaxへの文字列補間を使って構築し、SwiftSyntaxの型安全性を活用します。

// The expansion returns a tuple literal
return "((\(arg)), \(literal: arg.description))"

マクロの引数にアクセスする

引数にはnode.argumentsでアクセスできます。これはラベル付き式のリストです。

let args = node.arguments
for arg in args {
  print(arg.label?.text ?? "_", arg.expression)
}

診断情報を生成する

展開コンテキストを使って、マクロからコンパイラーの警告やエラーを出力します。

context.diagnose(Diagnostic(
  node: node,
  message: MyDiagnostic.missingArgument
))

SwiftSyntaxの構文ノード

SwiftSyntaxでは、すべての言語構造が、調査や構築が可能な型付き構文ノードとして表現されます。

import SwiftSyntax
let expr: ExprSyntax = "1 + 2"
print(type(of: expr)) // BinaryOperatorExprSyntax

マクロの衛生性

Swiftマクロはデフォルトで衛生的です。生成された名前が呼び出し側のスコープにある名前と衝突することはありません。

// Macro-generated variables get unique names internally
// preventing accidental shadowing in user code

Xcodeで展開する

Xcodeで任意のマクロ呼び出しを右クリックし、マクロを展開を選択すると、生成されたソースを確認できます。

#stringify(40 + 2)
// Xcode expands to: (40 + 2, "40 + 2")

理解度チェック

式マクロの実装は、どのプロトコルに準拠する必要がありますか。

レッスンのまとめ

@freestanding(expression)で宣言し、.macroターゲットでExpressionMacroを実装し、CompilerPluginで登録して、#macroName()で呼び出すことで、フリースタンディング式マクロを作成できます。

よくある質問

「フリースタンディング式マクロの記述」レッスンは無料ですか?

はい。「フリースタンディング式マクロの記述」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「フリースタンディング式マクロの記述」で何を学びますか?

SwiftSyntaxとMacroExpansionを使い、単純な#stringifyマクロを実装します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「フリースタンディング式マクロの記述」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. マクロの役割:フリースタンディングとアタッチド
  2. フリースタンディング式マクロの記述
  3. ボイラープレートを削減するアタッチドメンバーマクロ
  4. マクロのテストとデバッグ
← Swift Academyに戻る