Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
omochi authored Dec 21, 2022
1 parent e0159eb commit 1835bf5
Showing 1 changed file with 24 additions and 97 deletions.
121 changes: 24 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
# CodegenKit
# CodegenKit: Swift code generation framework

Swift code generation framework.
This is a framework for introducing code generation on your Swift project.
You can do meta-programming like below.

## Usage
## Code becomes template as it is

### Step1. Write code with placeholder

`@codegen(name)` and `@end` are placeholder marker.
Lines between them are edited by tool.
Placeholders are defined by markers in Swift code as follows.

```swift
// TSDecl.swift
protocol TSDecl {}

extension TSDecl {
Expand All @@ -19,14 +16,16 @@ extension TSDecl {
}
```

### Step2. Write yor renderer.
Generated codes are inserted in area between markers.

Thus, CodegenKit doesn't use any specific template files.
Instead, Swift source codes are used as a template.

Write your renderer that conforms to `CodegenKit.Renderer`.
It will get source as `CodeTemplate`.
You can edit placeholder via subscript.
## Write code renderer in Swift

Write code renderer as follows.

```swift
// TSDeclRenderer.swift
import Foundation
import CodegenKit

Expand Down Expand Up @@ -57,46 +56,19 @@ public var as\(node.stem.pascal): \(node.typeName)? { self as? \(node.typeName)
}
```

## Step3. Build your generator executable

Register your renderers to `CodegenKit.CodegenRunner` and invoke `run` method.
`CodegenRunner` scan applied directories recursively.

```swift
// main.swift
import Foundation
import CodegenKit

let runner = CodegenRunner(renderers: [
TSDeclRenderer()
])
try runner.run(directories: [URL(fileURLWithPath: ".")])
```
Your source code are passed as `CodeTemplate` object.
You can edit contents of placeholder via subscript.

```swift
let package = Package(
...
targets: [
...
.executableTarget(
name: "codegen",
dependencies: [
.product(name: "CodegenKit", package: "CodegenKit")
]
)
...
],
...
)
```
## Do code generation

## Step4. Run generator
After writing renderers, generate codes.
Perform code generation with following command.

```
$ swift run codegen
$ swift package codegen
```

You will get generated code.
Previous code will be edited as follows.

```swift
// TSDecl.swift
Expand All @@ -118,57 +90,12 @@ extension TSDecl {
}
```

CodegenKit automatically format generated code by [swift-format](https://github.com/apple/swift-format).
So you don't have to worry about precise textual control like indenting when write renderer.

## Step5. (optional) Build package plugin

If you write [command plugin](https://github.com/apple/swift-evolution/blob/main/proposals/0332-swiftpm-command-plugins.md),
you can invoke codegen from package plugin.

```
$ swift package codegen
```

See examples to know how do this.

## Examples

- [TypeScriptAST](https://github.com/omochi/TypeScriptAST)
- [SwiftTypeReader](https://github.com/omochi/SwiftTypeReader)

# CodeTemplate

Small library for support **in place** code generation.
You can use this module independently from CodegenKit.

## Usage

Write code as template with markers.

```swift
// Visitor.swift
class Visitor {
...

// @codegen(visitImpl)
func visitImpl(call: CallExpr) { ... }
func visitImpl(ident: IdentExpr) { ... }
// @end
}
```

Load code as template, edit, save.
Let's start and enjoy code generation!
Please read [this document](Docs/init.md) for detailed setup instructions.

```swift
let file = URL(fileURLWithPath: "Visitor.swift")
var template = try Template(file: file)
template["visitImpl"] = generateVisitImpl()
try template.description.write(to: file, atomically: true, encoding: .utf8)
```
# Documents

## Detail
- [Setup instructions](Docs/init.md)
- [CodeTemplateModule sublibrary](Docs/CodeTemplateModule.md)

CodeTemplate just split source file by lines.
It doesn't see any syntax like comments, so it's target language agnostic.

0 comments on commit 1835bf5

Please sign in to comment.