Skip to content

Commit

Permalink
Fix formatting and extra lines (#11)
Browse files Browse the repository at this point in the history
* Fix formatting and extra lines

* Update project indentation

* Fix tests failing do to removal of extra line

* Update code formatting
  • Loading branch information
0xLeif authored Nov 7, 2024
1 parent acdc634 commit a18d9b4
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 96 deletions.
6 changes: 3 additions & 3 deletions Sources/MockedClient/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import Mocked
protocol ExampleProtocol: Sendable {
associatedtype ItemType: Codable
associatedtype ItemValue: Equatable

var name: String { get set }
var count: Int { get }
var isEnabled: Bool { get set }

func fetchItem(withID id: Int) async throws -> ItemType
func saveItem(_ item: ItemType) throws -> Bool

func processAllItems() async
func reset()
func optionalItem() -> ItemType?
Expand Down
95 changes: 45 additions & 50 deletions Sources/MockedMacros/MockedMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public struct MockedMacro: PeerMacro {
)
return []
}

// Check for access level argument (e.g., @Mocked(.public))
var accessLevel: String = "internal"

if case let .argumentList(argumentList) = node.arguments {
// Process each argument in the list
for argument in argumentList {
Expand Down Expand Up @@ -70,59 +70,56 @@ public struct MockedMacro: PeerMacro {
}

let mockClassName = "Mocked\(protocolDecl.name.text)"

let members = protocolDecl.memberBlock.members

// Variables

let variables: [Variable] = variableBuilder(members: members)

let variablesDefinitions: String = variableDefinitions(variables: variables, accessLevel: accessLevel)
let variablesInitDefinitions: String = variablesInitDefinitions(variables: variables)
let variablesInitAssignments: String = variablesInitAssignments(variables: variables)

// Functions

let functions: [Function] = functionBuilder(
protocolDecl: protocolDecl,
members: members
)


let functions: [Function] = functionBuilder(protocolDecl: protocolDecl, members: members)

let functionVariableDefinitions: String = functionVariableDefinitions(functions: functions)
let functionVariableInitDefinitions: String = functionVariableInitDefinitions(functions: functions)
let functionVariableInitAssignments: String = functionVariableInitAssignments(functions: functions)
let functionImplementations: String = functionImplementations(functions: functions, accessLevel: accessLevel)

// Check if the protocol conforms to AnyObject
let requiresClassConformance = protocolDecl.inheritanceClause?.inheritedTypes.contains(where: {
$0.type.description.trimmingCharacters(in: .whitespacesAndNewlines) == "AnyObject"
}) ?? false
let requiresClassConformance = protocolDecl.inheritanceClause?.inheritedTypes.contains(
where: { $0.type.description.trimmingCharacters(in: .whitespacesAndNewlines) == "AnyObject" }
) ?? false

let objectType: String = requiresClassConformance ? "class" : "struct"

// Check for associated types in the protocol
var associatedTypes: [String] = []

for member in protocolDecl.memberBlock.members {
if let associatedTypeDecl = member.decl.as(AssociatedTypeDeclSyntax.self) {
let name = associatedTypeDecl.name.text
let constraint = associatedTypeDecl.inheritanceClause?.description.trimmingCharacters(in: .whitespacesAndNewlines)

if let constraint {
associatedTypes.append("\(name)\(constraint)")
} else {
associatedTypes.append(name)
}
}
}

// Construct generic type parameters if there are associated types
let genericValues = if associatedTypes.isEmpty {
""
} else {
"<" + associatedTypes.joined(separator: ", ") + ">"
}

return [
"""
/// Mocked version of \(raw: protocolDecl.name.text)
Expand All @@ -144,24 +141,23 @@ public struct MockedMacro: PeerMacro {
\(raw: variablesInitAssignments)
\(raw: functionVariableInitAssignments)
}
// MARK: - \(raw: mockClassName) Functions
\(raw: functionImplementations)
}
"""
]
}

// MARK: - Variable helpers

private static func variableBuilder(members: MemberBlockItemListSyntax) -> [Variable] {
members.compactMap { member in
guard
let variable = member.decl.as(VariableDeclSyntax.self)
else { return nil }

guard let binding = variable.bindings.first else {
return nil
}
Expand All @@ -170,18 +166,18 @@ public struct MockedMacro: PeerMacro {
else {
fatalError("\(String(describing: binding.initializer?.syntaxNodeType))")
}

let name = binding.pattern
let type = typeAnnotation.description.trimmingCharacters(in: .whitespacesAndNewlines)

return Variable(
firstName: "\(name)",
secondName: nil,
type: type
)
}
}

private static func variableDefinitions(
variables: [Variable],
accessLevel: String
Expand All @@ -198,50 +194,50 @@ public struct MockedMacro: PeerMacro {
}
.joined(separator: "\n")
}

private static func variablesInitDefinitions(
variables: [Variable]
) -> String {
variables
.map { "\($0.declaration)," }
.joined(separator: "\n")
}

private static func variablesInitAssignments(
variables: [Variable]
) -> String {
variables
.map { "self.\($0.name) = \($0.name)" }
.joined(separator: "\n")
}

// MARK: - Function helpers

private static func functionBuilder(
protocolDecl: ProtocolDeclSyntax,
members: MemberBlockItemListSyntax
) -> [Function] {
let inheritsSendable = protocolDecl.inheritanceClause?.inheritedTypes.contains { inheritedType in
inheritedType.type.description.trimmingCharacters(in: .whitespacesAndNewlines) == "Sendable"
} ?? false

return members.compactMap { member in
guard
let function = member.decl.as(FunctionDeclSyntax.self)
else { return nil }

let name = function.name.text
var parameters: [Variable] = []
let returnType = function.signature.returnClause?.type ?? "Void"

let isAsync = function.signature.effectSpecifiers?.asyncSpecifier != nil
let canThrow = function.signature.effectSpecifiers?.throwsClause?.throwsSpecifier != nil

for parameter in function.signature.parameterClause.parameters {
let parameterFirstName = parameter.firstName.text
let parameterSecondName = parameter.secondName?.text
let parameterType = parameter.type.description.trimmingCharacters(in: .whitespacesAndNewlines)

parameters.append(
Variable(
firstName: parameterFirstName,
Expand All @@ -250,7 +246,7 @@ public struct MockedMacro: PeerMacro {
)
)
}

return Function(
name: "\(name)",
parameters: parameters,
Expand All @@ -261,31 +257,31 @@ public struct MockedMacro: PeerMacro {
)
}
}

private static func functionVariableDefinitions(
functions: [Function]
) -> String {
functions
.map { "private let \($0.overrideClosure)" }
.joined(separator: "\n")
}

private static func functionVariableInitDefinitions(
functions: [Function]
) -> String {
functions
.map { "\($0.closure) = nil" }
.joined(separator: ",\n")
}

private static func functionVariableInitAssignments(
functions: [Function]
) -> String {
functions
.map { "self.\($0.overrideName) = \($0.uniqueName)" }
.joined(separator: "\n")
}

private static func functionImplementations(
functions: [Function],
accessLevel: String
Expand All @@ -299,8 +295,7 @@ public struct MockedMacro: PeerMacro {
let parameterUsage: String = function.parameters
.map(\.usageName)
.joined(separator: ", ")



let effectSignature: String = if function.canThrow && function.isAsync {
"async throws "
} else if function.canThrow {
Expand All @@ -310,7 +305,7 @@ public struct MockedMacro: PeerMacro {
} else {
""
}

let callSignature: String = if function.canThrow && function.isAsync {
"try await "
} else if function.canThrow {
Expand All @@ -320,15 +315,15 @@ public struct MockedMacro: PeerMacro {
} else {
""
}

let accessLevel: String = if accessLevel.contains("public") {
"public"
} else if accessLevel.contains("package") {
"package"
} else {
"internal"
}

if parameters.isEmpty {
return """
\(accessLevel) func \(function.name)() \(effectSignature)-> \(function.returnType ?? "Void") {
Expand Down
12 changes: 6 additions & 6 deletions Sources/MockedMacros/Types/Variable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,34 @@ struct Variable {
let firstName: String
let secondName: String?
let type: String

var name: String {
guard
let secondName,
firstName == "_"
else {
return firstName
}

return secondName
}

var parameterName: String {
guard let secondName else {
return firstName
}

return "\(firstName) \(secondName)"
}

var usageName: String {
guard let secondName else {
return firstName
}

return secondName
}

var declaration: String {
"\(name): \(type)"
}
Expand Down
Loading

0 comments on commit a18d9b4

Please sign in to comment.