Skip to content

Commit f74854c

Browse files
committed
Allow all types of returns
1 parent 07053cb commit f74854c

3 files changed

Lines changed: 27 additions & 28 deletions

File tree

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Otter can even run within a Swift macro by adding the `@Database` macro to a `st
7979
@Database
8080
struct DB {
8181
@Query("SELECT * FROM foo")
82-
var selectFooQuery: SelectFooDatabaseQuery
82+
var selectFooQuery: any SelectFooQuery
8383

8484
static var migrations: [String] {
8585
return [
@@ -111,7 +111,6 @@ that won't scale well beyond a fairly simple schema and a handfull of queries.
111111
#### Current Limitations
112112
* Since macros operate purely on the syntax, all queries must be within the `@Database` itself so it has access to the schema.
113113
* All generated types will be nested under the `@Database` struct.
114-
* All `@Query` definitions must define their type as the generated `typealias` by the `@Database` macro.
115114
* Any diagnostics will be on the entire string rather than the part that actually failed.
116115

117116
# Installation

Sources/OtterMacros/Syntax+Extensions.swift

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,38 @@ extension VariableDeclSyntax {
7272
return nil
7373
}
7474

75-
var getter: CodeBlockItemListSyntax? {
75+
func asMigrationsArray(in context: some MacroExpansionContext) -> [(String, ExprSyntax)] {
7676
for binding in bindings {
77-
guard let accessorBlock = binding.accessorBlock,
78-
// TODO: Handle explicit `get {}`, seems different than the `.getter`
79-
case let .getter(getter) = accessorBlock.accessors else { return nil }
80-
return getter
77+
if let accessorBlock = binding.accessorBlock,
78+
case let .getter(getter) = accessorBlock.accessors {
79+
// Has a getter block `{ return [] }`
80+
guard let stmt = getter.last?.item, getter.count == 1 else {
81+
context.addDiagnostics(from: SyntaxError("Migrations must have one statement returning [String]"), node: self)
82+
return []
83+
}
84+
85+
if let ret = stmt.as(ReturnStmtSyntax.self), let expr = ret.expression {
86+
return getMigrationsArray(expr: expr, in: context)
87+
} else if let expr = stmt.as(ExprSyntax.self) {
88+
return getMigrationsArray(expr: expr, in: context)
89+
} else {
90+
context.addDiagnostics(from: SyntaxError("Must be return statement"), node: self)
91+
return []
92+
}
93+
} else if let initializer = binding.initializer {
94+
// Set with a value `ident = value`
95+
return getMigrationsArray(expr: initializer.value, in: context)
96+
}
8197
}
8298

83-
return nil
99+
context.addDiagnostics(from: SyntaxError("Must have a getter that returns [String]"), node: self)
100+
return []
84101
}
85102

86-
func asMigrationsArray(in context: some MacroExpansionContext) -> [(String, ExprSyntax)] {
103+
func getMigrationsArray(expr: ExprSyntax, in context: some MacroExpansionContext) -> [(String, ExprSyntax)] {
87104
var strings: [(String, ExprSyntax)] = []
88105

89-
guard let getter else {
90-
context.addDiagnostics(from: SyntaxError("Must have a getter that returns [String]"), node: self)
91-
return strings
92-
}
93-
94-
guard let stmt = getter.last?.item, getter.count == 1 else {
95-
context.addDiagnostics(from: SyntaxError("Migrations must have one statement returning [String]"), node: self)
96-
return strings
97-
}
98-
99-
guard let ret = stmt.as(ReturnStmtSyntax.self) else {
100-
context.addDiagnostics(from: SyntaxError("Must be return statement"), node: self)
101-
return strings
102-
}
103-
104-
guard let array = ret.expression?.as(ArrayExprSyntax.self) else {
106+
guard let array = expr.as(ArrayExprSyntax.self) else {
105107
context.addDiagnostics(from: SyntaxError("Migrations must return an array literal"), node: self)
106108
return strings
107109
}

Tests/OtterTests/SQLAnyTests.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ struct SQLAnyTests {
4848
@Query("SELECT * FROM foo")
4949
var selectFoos: any SelectFoosQuery
5050

51-
static var migrations: [String] {
52-
return ["CREATE TABLE foo (bar ANY);"]
53-
}
51+
static let migrations: [String] = ["CREATE TABLE foo (bar ANY);"]
5452
}
5553
}

0 commit comments

Comments
 (0)