Skip to content

Commit

Permalink
Fix protocol composition and clean up the code.
Browse files Browse the repository at this point in the history
  • Loading branch information
Matyáš Kříž committed May 20, 2024
1 parent e26eb21 commit a756db9
Show file tree
Hide file tree
Showing 20 changed files with 392 additions and 219 deletions.
13 changes: 7 additions & 6 deletions .package.resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "a64ff5917cc2a5d0406bc10508197e31aa8e7eaacbc9e999a52bea35093394de",
"pins" : [
{
"identity" : "aexml",
Expand Down Expand Up @@ -57,7 +58,7 @@
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-argument-parser.git",
"location" : "https://github.com/apple/swift-argument-parser",
"state" : {
"revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
"version" : "1.2.3"
Expand All @@ -68,8 +69,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-cmark.git",
"state" : {
"revision" : "29d9c97e6310b87c4799268eaa2fc76164b2dbd8",
"version" : "0.2.0"
"revision" : "f218e5d7691f78b55bfa39b367763f4612486c35",
"version" : "0.3.0"
}
},
{
Expand All @@ -86,8 +87,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-markdown.git",
"state" : {
"revision" : "68b2fed9fb12fb71ac81e537f08bed430b189e35",
"version" : "0.2.0"
"revision" : "e4f95e2dc23097a1a9a1dfdfe3fe3ee44de77378",
"version" : "0.3.0"
}
},
{
Expand Down Expand Up @@ -118,5 +119,5 @@
}
}
],
"version" : 2
"version" : 3
}
293 changes: 148 additions & 145 deletions Cuckoo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

66 changes: 34 additions & 32 deletions Generator/Generator.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1010"
version = "1.7">
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
Expand Down Expand Up @@ -81,14 +81,21 @@
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "--configuration ../Cuckoofile"
argument = "--configuration ./Cuckoofile"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "--verbose"
isEnabled = "YES">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "PROJECT_DIR"
value = "/Users/matty/Documents/Work/Brightify/Cuckoo"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
5 changes: 4 additions & 1 deletion Generator/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,12 @@ let project = Project(
runAction: RunAction.runAction(
executable: "Cuckoonator",
arguments: Arguments(
environment: [
"PROJECT_DIR": Environment.projectDir.requireString(message: "TUIST_PROJECT_DIR environment property is required."),
],
launchArguments: [
// Any changes here should be reflected in `../Project.swift` as well.
LaunchArgument(name: "--configuration ../Cuckoofile", isEnabled: true),
LaunchArgument(name: "--configuration ./Cuckoofile", isEnabled: true),
LaunchArgument(name: "--verbose", isEnabled: true),
]
)
Expand Down
4 changes: 2 additions & 2 deletions Generator/Sources/CLI/Generator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class Generator {
.filter { $0.exists }
.map(TextFile.init(path:))

let files: [FileRepresentation] = inputFiles.compactMap { file in
let files: [FileRepresentation] = await inputFiles.concurrentCompactMap { file in
do {
log(.verbose, message: "Processing file: \(file.path)")
let crawler = try Crawler.crawl(url: file.path.url)
Expand Down Expand Up @@ -66,7 +66,7 @@ final class Generator {

let timestamp = verbose ? Date().description : nil
return try await mockableFiles.concurrentMap { file in
GeneratedFile(
await GeneratedFile(
path: file.file.path,
contents: [
module.options.omitHeaders ? nil : FileHeaderHandler.header(for: file, timestamp: timestamp),
Expand Down
13 changes: 9 additions & 4 deletions Generator/Sources/Internal/Crawlers/Crawler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ extension Crawler {
} else if let initializer = binding.initializer?.value.trimmed.description, let guessedType = TypeGuesser.guessType(from: initializer) {
type = .type(guessedType)
} else {
fatalError("Can't infer type: \(url)")
fatalError("Can't infer type of property '\(identifier)' in file \(url)")
}

let isReadOnly: Bool
Expand Down Expand Up @@ -504,6 +504,11 @@ class Multi {
// @available(*, renamed: "sameInstance(as:)")
// private(set) var geg: Stool
var gg: Dictionary<Int, String>
var ggwp: Array<String>
func compositionalParameters(param1: any Equatable & Numeric, param2: OnlyLabelProtocol & Codable)
@objc
var hammo: Tpikulka!
Expand All @@ -523,11 +528,11 @@ class Multi {
#if DEBUG
var pravda: Cool {
prdel
thing
}
#elseif RELEASE
var pravda: Cool {
prdel
some
}
#endif
Expand All @@ -540,7 +545,7 @@ class Multi {
}
protocol Brek<Crack: Codable> {
associatedtype gag: Encodable
associatedtype plak: Encodable
var asyncThrowsProperty: Int { get async throws }
var mutableProperty: Int { get set }
Expand Down
13 changes: 10 additions & 3 deletions Generator/Sources/Internal/GeneratorHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct GeneratorHelper {
@StaticActor
private static let extensions = createExtensions()

@StaticActor
static func generate(tokens: [Token], debug: Bool = false) throws -> String {
let containers = tokens.map { $0.serialize() }

Expand Down Expand Up @@ -76,7 +77,11 @@ struct GeneratorHelper {
var fullString = ""
for (index, parameter) in method.signature.parameters.enumerated() {
if !parameter.type.containsAttribute(named: "@escaping"), let closure = parameter.type.findClosure() {
let indents = String(repeating: "\t", count: index)
if fullString.isEmpty {
fullString = "\n"
}

let indents = String(repeating: "\t", count: index + 2)
let tries = method.isThrowing ? "try " : ""
let awaits = method.isAsync ? "await " : ""

Expand All @@ -90,15 +95,17 @@ struct GeneratorHelper {
fullString += "\(indents)return \(tries)\(awaits)withoutActuallyEscaping(\(parameter.usableName), do: { (\(parameter.usableName): @escaping \(parameter.type))\(returnSignature) in\n"
}
}

return fullString
}

private static func closeNestedClosure(for parameters: [MethodParameter]) -> String {
var fullString = ""
for (index, parameter) in parameters.enumerated() {
if !parameter.type.containsAttribute(named: "@escaping"), parameter.type.isClosure {
let indents = String(repeating: "\t", count: index)
if fullString.isEmpty {
fullString = "\n"
}
let indents = String(repeating: "\t", count: index + 2)
fullString += "\(indents)})\n"
}
}
Expand Down
30 changes: 29 additions & 1 deletion Generator/Sources/Internal/Helpers/Async+convenience.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ extension Sequence {

return values
}

func asyncCompactMap<T>(
_ transform: (Element) async throws -> T?
) async rethrows -> [T] {
var values = [T]()

for element in self {
if let value = try await transform(element) {
values.append(value)
}
}

return values
}
}

extension Sequence {
Expand Down Expand Up @@ -56,7 +70,7 @@ extension Sequence {
extension Sequence {
func concurrentMap<T>(
_ transform: @escaping (Element) async throws -> T
) async throws -> [T] {
) async rethrows -> [T] {
let tasks = map { element in
Task {
try await transform(element)
Expand All @@ -67,4 +81,18 @@ extension Sequence {
try await task.value
}
}

func concurrentCompactMap<T>(
_ transform: @escaping (Element) async throws -> T?
) async rethrows -> [T] {
let tasks = map { element in
Task {
try await transform(element)
}
}

return try await tasks.asyncCompactMap { task in
try await task.value
}
}
}
10 changes: 10 additions & 0 deletions Generator/Sources/Internal/Helpers/SwiftSyntax+convenience.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ extension ExprSyntaxProtocol {
}
}
}

extension IdentifierTypeSyntax {
var identifier: String {
if case .identifier(let identifier) = name.tokenKind {
return identifier
} else {
fatalError("Cuckoo error: Expected identifier. Please create an issue.")
}
}
}
11 changes: 5 additions & 6 deletions Generator/Sources/Internal/Templates/MockTemplate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extension {{ container.parentFullyQualifiedName }} {
{% endif -%}
{% for property in container.properties %}
{% if debug %}
// {{ property }}
{% endif %}
Expand All @@ -64,7 +65,7 @@ extension {{ container.parentFullyQualifiedName }} {
{% for attribute in property.attributes %}
{{ attribute }}
{% endfor %}
{{ property.accessibility|withSpace }}{% if property.isOverriding %}override {% endif %} var {{ property.name|escapeReservedKeywords }}: {{ property.type }} {
{{ property.accessibility|withSpace }}{% if property.isOverriding %}override {%+ endif %}var {{ property.name|escapeReservedKeywords }}: {{ property.type }} {
get {%+ if property.isAsync %}async {%+ endif %}{% if property.isThrowing %}throws {%+ endif %}{
return {%+ if property.isThrowing %}try {%+ endif %}{% if property.isAsync %}await {%+ endif %}cuckoo_manager.getter{% if property.isThrowing %}Throws{% endif %}(
"{{ property.name }}",
Expand Down Expand Up @@ -102,8 +103,8 @@ extension {{ container.parentFullyQualifiedName }} {
{% endfor %}
{{ initializer.accessibility|withSpace }}required init{{initializer.signature}} {}
{% endfor %}
{% for method in container.methods %}
{% if debug %}
// {{method}}
{% endif %}
Expand All @@ -114,15 +115,13 @@ extension {{ container.parentFullyQualifiedName }} {
{{ attribute }}
{% endfor %}
{{ method.accessibility|withSpace }}{% if method.isOverriding %}override {%+ endif %}func {{ method.name|escapeReservedKeywords }}{{ method.signature }} {
{{ method.self|openNestedClosure }}
return{% if method.isThrowing %} try{% endif %}{% if method.isAsync %} await{% endif %} cuckoo_manager.call{% if method.isThrowing %}{{ method.throwType|capitalize }}{% endif %}(
{{ method.self|openNestedClosure }}return{% if method.isThrowing %} try{% endif %}{% if method.isAsync %} await{% endif %} cuckoo_manager.call{% if method.isThrowing %}{{ method.throwType|capitalize }}{% endif %}(
"{{method.fullyQualifiedName}}",
parameters: ({{method.parameterNames}}),
escapingParameters: ({{method.escapingParameterNames}}),
superclassCall: {%+ if container.isImplementation %}{% if method.isAsync %}await {%+ endif %}super.{{method.name}}({{method.call}}){% else %}Cuckoo.MockManager.crashOnProtocolSuperclassCall(){% endif %},
defaultCall: {%+ if method.isAsync %}await {%+ endif %}__defaultImplStub!.{{method.name}}{%if method.isOptional %}!{%endif%}({{method.call}})
)
{{ method.parameters|closeNestedClosure }}
){{ method.parameters|closeNestedClosure }}
}
{% endfor %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension Templates {
{% for attribute in property.attributes %}
{{ attribute }}
{% endfor %}
{{ property.accessibility|withSpace }}{% if property.isOverriding %}override{% endif %} var {{ property.name }}: {{ property.type }} {
{{ property.accessibility|withSpace }}{% if property.isOverriding %}override {%+ endif %}var {{ property.name }}: {{ property.type }} {
get {
return DefaultValueRegistry.defaultValue(for: ({{property.type|genericSafe|removeClosureArgumentNames}}).self)
}
Expand Down Expand Up @@ -41,7 +41,7 @@ extension Templates {
{% for attribute in method.attributes %}
{{ attribute }}
{% endfor %}
{{ method.accessibility|withSpace }}{% if method.isOverriding %}override{% endif %} func {{ method.name|escapeReservedKeywords }}{{ method.signature }} {
{{ method.accessibility|withSpace }}{% if method.isOverriding %}override {%+ endif %}func {{ method.name|escapeReservedKeywords }}{{ method.signature }} {
return DefaultValueRegistry.defaultValue(for: ({{method.returnType|genericSafe}}).self)
}
{% if method.hasUnavailablePlatforms %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ extension Templates {
self.callMatcher = callMatcher
self.sourceLocation = sourceLocation
}
{% for property in container.properties %}
{% for attribute in property.attributes %}
{{ attribute }}
{% endfor %}
var {{property.name}}: Cuckoo.{{property.verifyType}}<{% if property.isReadOnly %}{{property.type|genericSafe}}{% else %}{{property.nonOptionalType|genericSafe}}{% endif %}> {
return .init(manager: cuckoo_manager, name: "{{property.name}}", callMatcher: callMatcher, sourceLocation: sourceLocation)
}
{% endfor %}
{% for method in container.methods %}
{{ method.unavailablePlatformsCheck }}
{% for attribute in method.attributes %}
{{ attribute }}
Expand Down
Loading

0 comments on commit a756db9

Please sign in to comment.