CodegenKit

2.1.1

Swift code generation framework
omochi/CodegenKit

What's New

2.1.1

2026-05-25T07:54:22Z

What's Changed

  • プラグイン生成機のコードを更新 by @omochi in #16

Full Changelog: 2.1.0...2.1.1

CodegenKit: a Swift code generation framework

CodegenKit helps you add lightweight code generation to Swift projects. It lets you keep generated code directly in your Swift source files, while still making the generated regions easy to update.

Swift Code As The Template

Placeholders are marked directly in Swift source code:

protocol TSDecl {}

extension TSDecl {
    // @codegen(as)
    // @end
}

Generated code is written between the // @codegen(...) and // @end markers. CodegenKit does not require separate template files; your Swift source files are the templates.

Write Renderers In Swift

A renderer decides which files it handles and writes generated code into named placeholders.

import Foundation
import CodegenKit

struct Node {
    var stem: String
    var typeName: String
}

struct TSDeclRenderer: Renderer {
    var nodes: [Node] = [...]

    func isTarget(file: URL) -> Bool {
        file.lastPathComponent == "TSDecl.swift"
    }

    func render(template: inout CodeTemplate, file: URL, on runner: CodegenRunner) throws {
        template["as"] = asCasts()
    }

    func asCasts() -> String {
        let lines: [String] = nodes.map { node in
            """
public var as\(node.stem.pascal): \(node.typeName)? { self as? \(node.typeName) }
"""
        }
        return lines.joined(separator: "\n")
    }
}

Source files are passed to renderers as CodeTemplate values. You can read and replace each placeholder through the template subscript.

Indentation

CodegenKit uses the indentation of the // @codegen(...) marker as the base indentation for generated code.

For example, this marker is indented by four spaces:

extension TSDecl {
    // @codegen(as)
    // @end
}

Every non-empty line assigned to template["as"] is written with those four spaces added.

Renderers should generate code from the left edge, without the marker's base indentation:

template["as"] = """
public var asClass: TSClassDecl? { self as? TSClassDecl }
public var asField: TSFieldDecl? { self as? TSFieldDecl }
"""

Keep relative indentation inside generated code. CodegenKit adds the marker's base indentation to each non-empty line, but it does not infer or rewrite the internal indentation of the generated code.

Run Code Generation

After writing renderers, run code generation with:

swift package codegen

The source file is updated in place:

// TSDecl.swift
protocol TSDecl {}

extension TSDecl {
    // @codegen(as)
    public var asClass: TSClassDecl? { self as? TSClassDecl }
    public var asField: TSFieldDecl? { self as? TSFieldDecl }
    public var asFunction: TSFunctionDecl? { self as? TSFunctionDecl }
    public var asImport: TSImportDecl? { self as? TSImportDecl }
    public var asInterface: TSInterfaceDecl? { self as? TSInterfaceDecl }
    public var asMethod: TSMethodDecl? { self as? TSMethodDecl }
    public var asNamespace: TSNamespaceDecl? { self as? TSNamespaceDecl }
    public var asSourceFile: TSSourceFile? { self as? TSSourceFile }
    public var asType: TSTypeDecl? { self as? TSTypeDecl }
    public var asVar: TSVarDecl? { self as? TSVarDecl }
    // @end
}

For setup details, see Setup instructions.

Documents

Description

  • Swift Tools 6.0.0
View More Packages from this Author

Dependencies

Last updated: Sun Sep 27 2026 04:31:22 GMT-0900 (Hawaii-Aleutian Daylight Time)