-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: fixed error with
private
access modifier on type declaration (#46
- Loading branch information
1 parent
12784b2
commit d378204
Showing
5 changed files
with
212 additions
and
35 deletions.
There are no files selected for viewing
File renamed without changes.
34 changes: 34 additions & 0 deletions
34
Sources/CodableMacroPlugin/Registration/Options/DeclModifiersGenerator.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
@_implementationOnly import SwiftSyntax | ||
|
||
extension Registrar.Options { | ||
/// A declaration modifiers generator for `Codable` | ||
/// conformance implementations. | ||
/// | ||
/// This generator keeps track of original declaration | ||
/// and modifiers, then generates modifiers for | ||
/// `Decodable` or `Encodable` implementations. | ||
struct DeclModifiersGenerator { | ||
/// The declaration for which modifiers generated. | ||
let decl: DeclGroupSyntax | ||
|
||
/// The generated list of modifiers. | ||
/// | ||
/// If declaration has `public` or `package` modifier | ||
/// then same is generated, otherwise no extra modifiers | ||
/// generated. | ||
var generated: DeclModifierListSyntax { | ||
let `public` = DeclModifierSyntax(name: "public") | ||
let package = DeclModifierSyntax(name: "package") | ||
var modifiers = DeclModifierListSyntax() | ||
let accessModifier = [`public`, package].first { accessModifier in | ||
decl.modifiers.contains { modifier in | ||
modifier.name.text == accessModifier.name.text | ||
} | ||
} | ||
if let accessModifier { | ||
modifiers.append(accessModifier) | ||
} | ||
return modifiers | ||
} | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
Sources/CodableMacroPlugin/Registration/Options/Options.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
@_implementationOnly import SwiftSyntax | ||
|
||
extension Registrar { | ||
/// A type indicating various configurations available | ||
/// for `Registrar`. | ||
/// | ||
/// These options are used as global level customization | ||
/// performed on the final generated implementation | ||
/// of `Codable` conformance. | ||
struct Options { | ||
/// The list of modifiers generator for | ||
/// conformance implementation declarations. | ||
let modifiersGenerator: DeclModifiersGenerator | ||
/// The where clause generator for generic type arguments. | ||
let constraintGenerator: ConstraintGenerator | ||
|
||
/// Memberwise initialization generator with provided options. | ||
/// | ||
/// Creates memberwise initialization generator by passing | ||
/// the provided access modifiers. | ||
var initGenerator: MemberwiseInitGenerator { | ||
let modifiers = modifiersGenerator.generated | ||
return .init(options: .init(modifiers: modifiers)) | ||
} | ||
|
||
/// Creates a new options instance with provided declaration group. | ||
/// | ||
/// - Parameters: | ||
/// - decl: The declaration group options will be applied to. | ||
/// | ||
/// - Returns: The newly created options. | ||
init(decl: DeclGroupSyntax) { | ||
self.modifiersGenerator = .init(decl: decl) | ||
self.constraintGenerator = .init(decl: decl) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
#if SWIFT_SYNTAX_EXTENSION_MACRO_FIXED | ||
import XCTest | ||
|
||
@testable import CodableMacroPlugin | ||
|
||
final class AccessModifierTests: XCTestCase { | ||
|
||
func testPublic() throws { | ||
assertMacroExpansion( | ||
""" | ||
@Codable | ||
@MemberInit | ||
public struct SomeCodable { | ||
let value: String | ||
} | ||
""", | ||
expandedSource: | ||
""" | ||
public struct SomeCodable { | ||
let value: String | ||
public init(value: String) { | ||
self.value = value | ||
} | ||
} | ||
extension SomeCodable: Decodable { | ||
public init(from decoder: any Decoder) throws { | ||
let container = try decoder.container(keyedBy: CodingKeys.self) | ||
self.value = try container.decode(String.self, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable: Encodable { | ||
public func encode(to encoder: any Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
try container.encode(self.value, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable { | ||
enum CodingKeys: String, CodingKey { | ||
case value = "value" | ||
} | ||
} | ||
""" | ||
) | ||
} | ||
|
||
func testPackage() throws { | ||
assertMacroExpansion( | ||
""" | ||
@Codable | ||
@MemberInit | ||
package struct SomeCodable { | ||
let value: String | ||
} | ||
""", | ||
expandedSource: | ||
""" | ||
package struct SomeCodable { | ||
let value: String | ||
package init(value: String) { | ||
self.value = value | ||
} | ||
} | ||
extension SomeCodable: Decodable { | ||
package init(from decoder: any Decoder) throws { | ||
let container = try decoder.container(keyedBy: CodingKeys.self) | ||
self.value = try container.decode(String.self, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable: Encodable { | ||
package func encode(to encoder: any Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
try container.encode(self.value, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable { | ||
enum CodingKeys: String, CodingKey { | ||
case value = "value" | ||
} | ||
} | ||
""" | ||
) | ||
} | ||
|
||
func testOthers() throws { | ||
for modifier in ["internal", "fileprivate", "private", ""] { | ||
let prefix = modifier.isEmpty ? "" : "\(modifier) " | ||
assertMacroExpansion( | ||
""" | ||
@Codable | ||
@MemberInit | ||
\(prefix)struct SomeCodable { | ||
let value: String | ||
} | ||
""", | ||
expandedSource: | ||
""" | ||
\(prefix)struct SomeCodable { | ||
let value: String | ||
init(value: String) { | ||
self.value = value | ||
} | ||
} | ||
extension SomeCodable: Decodable { | ||
init(from decoder: any Decoder) throws { | ||
let container = try decoder.container(keyedBy: CodingKeys.self) | ||
self.value = try container.decode(String.self, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable: Encodable { | ||
func encode(to encoder: any Encoder) throws { | ||
var container = encoder.container(keyedBy: CodingKeys.self) | ||
try container.encode(self.value, forKey: CodingKeys.value) | ||
} | ||
} | ||
extension SomeCodable { | ||
enum CodingKeys: String, CodingKey { | ||
case value = "value" | ||
} | ||
} | ||
""" | ||
) | ||
} | ||
} | ||
} | ||
#endif |