Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,19 @@ extension Registration where Var: DefaultPropertyVariable {
from decl: some AttributableDeclSyntax
) -> Registration<Decl, Key, StrategyVariable<Var.Initialization>> {
let finder = StrategyFinder(decl: decl)
let inStrategy =
finder.valueCodingStrategies.first { strategy in
strategy.trimmedDescription
== self.variable.type.trimmedDescription
} != nil
let type = finder.valueCodingStrategies.first { strategy in
return strategy.trimmedDescription
== self.variable.type.trimmedDescription
|| strategy.trimmedDescription
== self.variable.type.wrappedType.trimmedDescription
}

let newVariable: AnyPropertyVariable<Var.Initialization>
if inStrategy {
if let type = type {
newVariable =
HelperCodedVariable(
base: self.variable,
options: .helper("ValueCoder<\(variable.type)>()")
options: .helper("ValueCoder<\(type)>()")
).any
} else {
newVariable = self.variable.any
Expand Down
43 changes: 24 additions & 19 deletions Sources/PluginCore/Variables/Property/PropertyVariable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,35 +195,40 @@ extension CodeBlockItemListSyntax: ConditionalVariableSyntax {
}

extension TypeSyntax {
/// Check whether current type syntax represents an optional type.
/// Extract actual type of an optional type.
///
/// Checks whether the type syntax uses
/// Extracts type based on whether the type syntax uses
/// `?` optional type syntax (i.e. `Type?`) or
/// `!` implicitly unwrapped optional type syntax (i.e. `Type!`) or
/// generic optional syntax (i.e. `Optional<Type>`).
var isOptionalTypeSyntax: Bool {
if self.is(OptionalTypeSyntax.self) {
return true
} else if self.is(ImplicitlyUnwrappedOptionalTypeSyntax.self) {
return true
} else if let type = self.as(IdentifierTypeSyntax.self),
type.name.trimmed.text == "Optional",
let gArgs = type.genericArgumentClause?.arguments,
gArgs.count == 1
/// Otherwise, returns the type syntax as is.
var wrappedType: TypeSyntax {
if let type = self.as(OptionalTypeSyntax.self) {
return type.wrappedType
} else if let type = self.as(ImplicitlyUnwrappedOptionalTypeSyntax.self)
{
return true
} else if let type = self.as(MemberTypeSyntax.self),
let baseType = type.baseType.as(IdentifierTypeSyntax.self),
baseType.trimmed.name.text == "Swift",
type.trimmed.name.text == "Optional",
return type.wrappedType
} else if let type = self.as(IdentifierTypeSyntax.self),
type.name.text == "Optional",
let gArgs = type.genericArgumentClause?.arguments,
gArgs.count == 1
gArgs.count == 1,
let wrappedType = gArgs.first?.argument.as(TypeSyntax.self)
{
return true
return wrappedType
} else {
return false
return self
}
}

/// Check whether current type syntax represents an optional type.
///
/// Checks whether the type syntax uses
/// `?` optional type syntax (i.e. `Type?`) or
/// `!` implicitly unwrapped optional type syntax (i.e. `Type!`) or
/// generic optional syntax (i.e. `Optional<Type>`).
var isOptionalTypeSyntax: Bool {
wrappedType != self
}
}

#if swift(<6.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ struct CommonStrategiesValueCoderTests {
let int: Int
let double: Double
let string: String
let optBool: Bool?
let optInt: Int?
let optDouble: Double?
let optString: String?
let impBool: Bool!
let impInt: Int!
let impDouble: Double!
let impString: String!
let optGenBool: Optional<Bool>
let optGenInt: Optional<Int>
let optGenDouble: Optional<Double>
let optGenString: Optional<String>
}

@Test
Expand Down Expand Up @@ -54,6 +66,18 @@ struct CommonStrategiesValueCoderTests {
let int: Int
let double: Double
let string: String
let optBool: Bool?
let optInt: Int?
let optDouble: Double?
let optString: String?
let impBool: Bool!
let impInt: Int!
let impDouble: Double!
let impString: String!
let optGenBool: Optional<Bool>
let optGenInt: Optional<Int>
let optGenDouble: Optional<Double>
let optGenString: Optional<String>
}
""",
expandedSource:
Expand All @@ -63,6 +87,18 @@ struct CommonStrategiesValueCoderTests {
let int: Int
let double: Double
let string: String
let optBool: Bool?
let optInt: Int?
let optDouble: Double?
let optString: String?
let impBool: Bool!
let impInt: Int!
let impDouble: Double!
let impString: String!
let optGenBool: Optional<Bool>
let optGenInt: Optional<Int>
let optGenDouble: Optional<Double>
let optGenString: Optional<String>
}

extension Model: Decodable {
Expand All @@ -72,6 +108,18 @@ struct CommonStrategiesValueCoderTests {
self.int = try ValueCoder<Int>().decode(from: container, forKey: CodingKeys.int)
self.double = try ValueCoder<Double>().decode(from: container, forKey: CodingKeys.double)
self.string = try ValueCoder<String>().decode(from: container, forKey: CodingKeys.string)
self.optBool = try ValueCoder<Bool>().decodeIfPresent(from: container, forKey: CodingKeys.optBool)
self.optInt = try ValueCoder<Int>().decodeIfPresent(from: container, forKey: CodingKeys.optInt)
self.optDouble = try ValueCoder<Double>().decodeIfPresent(from: container, forKey: CodingKeys.optDouble)
self.optString = try ValueCoder<String>().decodeIfPresent(from: container, forKey: CodingKeys.optString)
self.impBool = try ValueCoder<Bool>().decodeIfPresent(from: container, forKey: CodingKeys.impBool)
self.impInt = try ValueCoder<Int>().decodeIfPresent(from: container, forKey: CodingKeys.impInt)
self.impDouble = try ValueCoder<Double>().decodeIfPresent(from: container, forKey: CodingKeys.impDouble)
self.impString = try ValueCoder<String>().decodeIfPresent(from: container, forKey: CodingKeys.impString)
self.optGenBool = try ValueCoder<Bool>().decodeIfPresent(from: container, forKey: CodingKeys.optGenBool)
self.optGenInt = try ValueCoder<Int>().decodeIfPresent(from: container, forKey: CodingKeys.optGenInt)
self.optGenDouble = try ValueCoder<Double>().decodeIfPresent(from: container, forKey: CodingKeys.optGenDouble)
self.optGenString = try ValueCoder<String>().decodeIfPresent(from: container, forKey: CodingKeys.optGenString)
}
}

Expand All @@ -82,6 +130,18 @@ struct CommonStrategiesValueCoderTests {
try ValueCoder<Int>().encode(self.int, to: &container, atKey: CodingKeys.int)
try ValueCoder<Double>().encode(self.double, to: &container, atKey: CodingKeys.double)
try ValueCoder<String>().encode(self.string, to: &container, atKey: CodingKeys.string)
try ValueCoder<Bool>().encodeIfPresent(self.optBool, to: &container, atKey: CodingKeys.optBool)
try ValueCoder<Int>().encodeIfPresent(self.optInt, to: &container, atKey: CodingKeys.optInt)
try ValueCoder<Double>().encodeIfPresent(self.optDouble, to: &container, atKey: CodingKeys.optDouble)
try ValueCoder<String>().encodeIfPresent(self.optString, to: &container, atKey: CodingKeys.optString)
try ValueCoder<Bool>().encodeIfPresent(self.impBool, to: &container, atKey: CodingKeys.impBool)
try ValueCoder<Int>().encodeIfPresent(self.impInt, to: &container, atKey: CodingKeys.impInt)
try ValueCoder<Double>().encodeIfPresent(self.impDouble, to: &container, atKey: CodingKeys.impDouble)
try ValueCoder<String>().encodeIfPresent(self.impString, to: &container, atKey: CodingKeys.impString)
try ValueCoder<Bool>().encodeIfPresent(self.optGenBool, to: &container, atKey: CodingKeys.optGenBool)
try ValueCoder<Int>().encodeIfPresent(self.optGenInt, to: &container, atKey: CodingKeys.optGenInt)
try ValueCoder<Double>().encodeIfPresent(self.optGenDouble, to: &container, atKey: CodingKeys.optGenDouble)
try ValueCoder<String>().encodeIfPresent(self.optGenString, to: &container, atKey: CodingKeys.optGenString)
}
}

Expand All @@ -91,6 +151,18 @@ struct CommonStrategiesValueCoderTests {
case int = "int"
case double = "double"
case string = "string"
case optBool = "optBool"
case optInt = "optInt"
case optDouble = "optDouble"
case optString = "optString"
case impBool = "impBool"
case impInt = "impInt"
case impDouble = "impDouble"
case impString = "impString"
case optGenBool = "optGenBool"
case optGenInt = "optGenInt"
case optGenDouble = "optGenDouble"
case optGenString = "optGenString"
}
}
"""
Expand Down
Loading