Skip to content

Commit

Permalink
Optional Instantiator and ForwardingInstantiator Support (#45)
Browse files Browse the repository at this point in the history
Co-authored-by: Dan Federman <[email protected]>
  • Loading branch information
MrAdamBoyd and dfed authored Jan 27, 2024
1 parent faeb519 commit c18dcdc
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
25 changes: 23 additions & 2 deletions Sources/SafeDICore/Generators/ScopeGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,14 @@ actor ScopeGenerator: CustomStringConvertible {
switch property.propertyType {
case .instantiator, .forwardingInstantiator:
isConstant = false
propertyDeclaration = "let \(property.label)"
leadingConcreteTypeName = property.typeDescription.asSource
let typeDescription = property.typeDescription.asSource
let unwrappedTypeDescription = property.typeDescription.unwrappedTypeDescription.asSource
if typeDescription == unwrappedTypeDescription {
propertyDeclaration = "let \(property.label)"
} else {
propertyDeclaration = "let \(property.label): \(typeDescription)"
}
leadingConcreteTypeName = unwrappedTypeDescription
case .constant:
isConstant = true
if concreteTypeName == property.typeDescription.asSource {
Expand Down Expand Up @@ -331,3 +337,18 @@ extension Instantiable {
) ?? "/* @Instantiable type is incorrectly configured. Fix errors from @Instantiable macro to fix this error. */"
}
}

// MARK: TypeDescription

extension TypeDescription {
fileprivate var unwrappedTypeDescription: TypeDescription {
switch self {
case
let .optional(type),
let .implicitlyUnwrappedOptional(type):
return type.unwrappedTypeDescription
case .any, .array, .attributed, .closure, .composition, .dictionary, .metatype, .nested, .simple, .some, .tuple, .unknown, .void:
return self
}
}
}
36 changes: 24 additions & 12 deletions Sources/SafeDICore/Models/Property.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,7 @@ public struct Property: Codable, Hashable, Comparable, Sendable {
}

var propertyType: PropertyType {
switch typeDescription {
case let .simple(name, _):
if name == Dependency.instantiatorType {
return .instantiator
} else if name == Dependency.forwardingInstantiatorType {
return .forwardingInstantiator
} else {
return .constant
}
case .any, .array, .attributed, .closure, .composition, .dictionary, .implicitlyUnwrappedOptional, .metatype, .nested, .optional, .some, .tuple, .unknown, .void:
return .constant
}
typeDescription.propertyType
}

var generics: [TypeDescription] {
Expand All @@ -152,3 +141,26 @@ public struct Property: Codable, Hashable, Comparable, Sendable {
case forwardingInstantiator
}
}

// MARK: TypeDescription

extension TypeDescription {
fileprivate var propertyType: Property.PropertyType {
switch self {
case let .simple(name, _):
if name == Dependency.instantiatorType {
return .instantiator
} else if name == Dependency.forwardingInstantiatorType {
return .forwardingInstantiator
} else {
return .constant
}
case
let .optional(type),
let .implicitlyUnwrappedOptional(type):
return type.propertyType
case .any, .array, .attributed, .closure, .composition, .dictionary, .metatype, .nested, .some, .tuple, .unknown, .void:
return .constant
}
}
}
37 changes: 37 additions & 0 deletions Tests/SafeDIToolTests/SafeDIToolTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3575,6 +3575,43 @@ final class SafeDIToolTests: XCTestCase {
)
}

func test_run_writesConvenienceExtensionOnRootOfTree_whenRootPropertyWithOptionalInstantiator() async throws {
let output = try await executeSystemUnderTest(
swiftFileContent: [
"""
@Instantiable
public final class Root {
@Instantiated
let childBuilder: Instantiator<Child>?
}
""",
"""
@Instantiable
public final class Child {}
""",
],
buildDependencyTreeOutput: true
)

XCTAssertEqual(
try XCTUnwrap(output.dependencyTree),
"""
// This file was generated by the SafeDIGenerateDependencyTree build tool plugin.
// Any modifications made to this file will be overwritten on subsequent builds.
// Please refrain from editing this file directly.
extension Root {
public convenience init() {
let childBuilder: Instantiator<Child>? = Instantiator<Child> {
Child()
}
self.init(childBuilder: childBuilder)
}
}
"""
)
}

// MARK: Error Tests

func test_run_onCodeWithPropertyWithUnknownFulfilledType_throwsError() async {
Expand Down

0 comments on commit c18dcdc

Please sign in to comment.