Skip to content

Commit

Permalink
generate type with Hashable and Equatable conformance
Browse files Browse the repository at this point in the history
  • Loading branch information
liamnichols committed Jul 26, 2024
1 parent f9dfc7d commit 638d847
Show file tree
Hide file tree
Showing 18 changed files with 276 additions and 26 deletions.
4 changes: 4 additions & 0 deletions Sources/StringGenerator/Extensions/TokenSyntax+Types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ extension TokenSyntax {
case LocalizedStringKey
case Text
case Sendable
case Hasher
case Bool
case Equatable
case Hashable
}

static func type(_ value: MetaType) -> TokenSyntax {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct StringStringsTableArgumentEnumSnippet: Snippet {
}

var inheritanceClause: InheritanceClauseSyntax? {
InheritanceClauseSyntax(.Sendable)
InheritanceClauseSyntax(.Equatable, .Hashable, .Sendable)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import SwiftSyntax
import SwiftSyntaxBuilder

struct StringStringsTableComparisonFunctionSnippet: Snippet {
let stringsTable: SourceFile.StringExtension.StringsTableStruct
let leftArg: TokenSyntax = "lhs"
let rightArg: TokenSyntax = "rhs"

var syntax: some DeclSyntaxProtocol {
FunctionDeclSyntax(
modifiers: modifiers,
name: .binaryOperator("=="),
signature: FunctionSignatureSyntax(
parameterClause: FunctionParameterClauseSyntax {
FunctionParameterSyntax(
firstName: leftArg,
type: IdentifierTypeSyntax(name: stringsTable.type)
)
FunctionParameterSyntax(
firstName: rightArg,
type: IdentifierTypeSyntax(name: stringsTable.type)
)
},
returnClause: ReturnClauseSyntax(type: .identifier(.Bool))
),
body: CodeBlockSyntax(statements: body)
)
}

@DeclModifierListBuilder
var modifiers: DeclModifierListSyntax {
DeclModifierSyntax(name: stringsTable.accessLevel.token)
DeclModifierSyntax(name: .keyword(.static))
}

var body: CodeBlockItemListSyntax {
// Array of `lhs.foo == rhs.foo`
var comparisons = stringsTable.comparableProperties.map { property in
InfixOperatorExprSyntax(
leftOperand: MemberAccessExprSyntax(leftArg, property.name),
operator: BinaryOperatorExprSyntax(operator: .binaryOperator("==")),
rightOperand: MemberAccessExprSyntax(rightArg, property.name)
)
}

var next = comparisons.removeLast()
while !comparisons.isEmpty {
let left = comparisons.removeLast()

next = InfixOperatorExprSyntax(
leftOperand: left,
operator: BinaryOperatorExprSyntax(operator: .binaryOperator("&&")),
rightOperand: next
)
}

return [CodeBlockItemSyntax(item: .expr(ExprSyntax(next)))]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import SwiftSyntax
import SwiftSyntaxBuilder

struct StringStringsTableHashIntoFunctionSnippet: Snippet {
let stringsTable: SourceFile.StringExtension.StringsTableStruct
let hasherToken: TokenSyntax = "hasher"

var syntax: some DeclSyntaxProtocol {
FunctionDeclSyntax(
modifiers: modifiers,
name: "hash",
signature: FunctionSignatureSyntax(
parameterClause: FunctionParameterClauseSyntax {
FunctionParameterSyntax(
firstName: "into",
secondName: hasherToken,
type: AttributedTypeSyntax(
specifiers: TypeSpecifierListSyntax {
SimpleTypeSpecifierSyntax(specifier: .keyword(.inout))
},
baseType: IdentifierTypeSyntax(name: .type(.Hasher))
)
)
}
),
body: CodeBlockSyntax(statements: body)
)
}

@DeclModifierListBuilder
var modifiers: DeclModifierListSyntax {
DeclModifierSyntax(name: stringsTable.accessLevel.token)
}

@CodeBlockItemListBuilder
var body: CodeBlockItemListSyntax {
for property in stringsTable.comparableProperties {
FunctionCallExprSyntax(callee: MemberAccessExprSyntax(hasherToken, "combine")) {
LabeledExprSyntax(expression: DeclReferenceExprSyntax(baseName: property.name))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct StringStringsTableStructSnippet: Snippet {
}

var inheritanceClause: InheritanceClauseSyntax? {
InheritanceClauseSyntax(.Sendable)
InheritanceClauseSyntax(.Equatable, .Hashable, .Sendable)
}

var memberBlock: MemberBlockSyntax {
Expand Down Expand Up @@ -112,6 +112,20 @@ struct StringStringsTableStructSnippet: Snippet {
StringStringsTableUnderscoredKeyComputedPropertySnippet(
stringsTable: stringsTable
)
.syntax
.with(\.trailingTrivia, .newlines(2))

// func hash(into hasher: Hasher) { ... }
StringStringsTableHashIntoFunctionSnippet(
stringsTable: stringsTable
)
.syntax
.with(\.trailingTrivia, .newlines(2))

// static func ==(lhs: Localizable, rhs: Localizable) -> Bool { ... }
StringStringsTableComparisonFunctionSnippet(
stringsTable: stringsTable
)
}
}

Expand Down
10 changes: 10 additions & 0 deletions Tests/PluginTests/PluginTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,14 @@ final class PluginTests: XCTestCase {
"Hello John, I have 1 plural"
)
}

func testComparisons() {
let foo1 = String.Localizable.demoBasic
let foo2 = String.Localizable.demoBasic
XCTAssertEqual(foo1, foo2)

let bar1 = String.Localizable.multiline(1)
let bar2 = String.Localizable.multiline(2)
XCTAssertNotEqual(bar1, bar2)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct FormatSpecifiers: Sendable {
internal struct FormatSpecifiers: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -335,6 +335,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: FormatSpecifiers, rhs: FormatSpecifiers) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(formatSpecifiers: FormatSpecifiers, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Localizable: Sendable {
internal struct Localizable: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -196,6 +196,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Localizable, rhs: Localizable) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(localizable: Localizable, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Multiline: Sendable {
internal struct Multiline: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -142,6 +142,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Multiline, rhs: Multiline) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(multiline: Multiline, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Positional: Sendable {
internal struct Positional: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -174,6 +174,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Positional, rhs: Positional) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(positional: Positional, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Simple: Sendable {
internal struct Simple: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -137,6 +137,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Simple, rhs: Simple) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(simple: Simple, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Substitution: Sendable {
internal struct Substitution: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -141,6 +141,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Substitution, rhs: Substitution) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(substitution: Substitution, locale: Locale? = nil) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ extension String {
/// ```
///
/// - SeeAlso: [XCStrings Tool Documentation - Using the generated source code](https://swiftpackageindex.com/liamnichols/xcstrings-tool/0.5.2/documentation/documentation/using-the-generated-source-code)
internal struct Variations: Sendable {
internal struct Variations: Equatable, Hashable, Sendable {
#if !SWIFT_PACKAGE
private class BundleLocator {
}
#endif

enum Argument: Sendable {
enum Argument: Equatable, Hashable, Sendable {
case int(Int)
case uint(UInt)
case float(Float)
Expand Down Expand Up @@ -152,6 +152,16 @@ extension String {
fileprivate var _key: String {
String(describing: key)
}

internal func hash(into hasher: inout Hasher) {
hasher.combine(_key)
hasher.combine(arguments)
hasher.combine(table)
}

internal static func ==(lhs: Variations, rhs: Variations) -> Bool {
lhs._key == rhs._key && lhs.arguments == rhs.arguments && lhs.table == rhs.table
}
}

internal init(variations: Variations, locale: Locale? = nil) {
Expand Down
Loading

0 comments on commit 638d847

Please sign in to comment.