Skip to content

Commit

Permalink
Generate overloads of onEnum to add support for using optional argume…
Browse files Browse the repository at this point in the history
…nts.
  • Loading branch information
FilipDolnik committed Nov 20, 2023
1 parent aa4ad90 commit ff48e3a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 11 deletions.
2 changes: 1 addition & 1 deletion SKIE/acceptance-tests
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import co.touchlab.skie.sir.element.SirValueParameter
import co.touchlab.skie.sir.element.copyTypeParametersFrom
import co.touchlab.skie.sir.element.toTypeFromEnclosingTypeParameters
import co.touchlab.skie.sir.element.toTypeParameterUsage
import co.touchlab.skie.sir.type.SirType
import co.touchlab.skie.sir.type.toNullable
import io.outfoxx.swiftpoet.CodeBlock
import io.outfoxx.swiftpoet.TypeName

Expand All @@ -20,10 +22,36 @@ class SealedFunctionGeneratorDelegate(

context(SirPhase.Context)
fun generate(kirClass: KirClass, enum: SirClass) {
val requiredFunction = generateRequiredOverload(kirClass, enum)
generateOptionalOverload(kirClass, enum, requiredFunction)
}

private fun generateRequiredOverload(kirClass: KirClass, enum: SirClass): SirSimpleFunction =
createFunctionDeclaration(kirClass, enum).apply {
addRequiredFunctionBody(kirClass, enum)
}

private fun generateOptionalOverload(kirClass: KirClass, enum: SirClass, requiredFunction: SirSimpleFunction) {
createFunctionDeclaration(
kirClass = kirClass,
enum = enum,
valueParameterType = { it.toNullable() },
returnTypeModifier = { it.toNullable() },
).apply {
addOptionalFunctionBody(requiredFunction)
}
}

private fun createFunctionDeclaration(
kirClass: KirClass,
enum: SirClass,
valueParameterType: (SirType) -> SirType = { it },
returnTypeModifier: (SirType) -> SirType = { it },
): SirSimpleFunction =
SirSimpleFunction(
identifier = kirClass.enumConstructorFunctionName,
parent = skieNamespaceProvider.getNamespaceFile(kirClass),
returnType = enum.toTypeFromEnclosingTypeParameters(enum.typeParameters),
parent = context.skieNamespaceProvider.getNamespaceFile(kirClass),
returnType = enum.toTypeFromEnclosingTypeParameters(enum.typeParameters).let(returnTypeModifier),
).apply {
copyTypeParametersFrom(enum)

Expand All @@ -37,12 +65,9 @@ class SealedFunctionGeneratorDelegate(
SirValueParameter(
label = kirClass.enumConstructorArgumentLabel,
name = kirClass.enumConstructorParameterName,
type = sealedTypeParameter.toTypeParameterUsage(),
type = sealedTypeParameter.toTypeParameterUsage().let(valueParameterType),
)

addFunctionBody(kirClass, enum)
}
}

private val KirClass.enumConstructorFunctionName: String
get() = configurationProvider.getConfiguration(this, SealedInterop.Function.Name)
Expand All @@ -53,7 +78,7 @@ class SealedFunctionGeneratorDelegate(
private val KirClass.enumConstructorParameterName: String
get() = configurationProvider.getConfiguration(this, SealedInterop.Function.ParameterName)

private fun SirSimpleFunction.addFunctionBody(
private fun SirSimpleFunction.addRequiredFunctionBody(
kirClass: KirClass,
enum: SirClass,
) {
Expand Down Expand Up @@ -132,4 +157,22 @@ class SealedFunctionGeneratorDelegate(
private fun CodeBlock.Builder.addReturnElse(kirClass: KirClass, enumType: TypeName) {
add("return %T.%N\n", enumType, kirClass.elseCaseName)
}

private fun SirSimpleFunction.addOptionalFunctionBody(requiredFunction: SirSimpleFunction) {
bodyBuilder.add {
val valueParameter = valueParameters.first()

val escapedParameterName = CodeBlock.toString("%N", valueParameter.name)

addCode(
CodeBlock.builder()
.beginControlFlow("if", "let $escapedParameterName")
.add("return %L as %T", requiredFunction.call(escapedParameterName), requiredFunction.returnType.evaluate().swiftPoetTypeName)
.nextControlFlow("else")
.add("return nil")
.endControlFlow("else")
.build(),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ sealed class Signature {
override fun toString(): String =
("static ".takeIf { scope == Scope.Static } ?: "") +
"func " +
"$receiver.".takeIf { receiver !is Receiver.None } +
("$receiver.".takeIf { receiver !is Receiver.None } ?: "") +
identifier +
"(${valueParameters.joinToString()})" +
" -> $returnType"
Expand Down Expand Up @@ -75,7 +75,7 @@ sealed class Signature {
override fun toString(): String =
("static ".takeIf { scope == Scope.Static } ?: "") +
"var " +
"$receiver.".takeIf { receiver !is Receiver.None } +
("$receiver.".takeIf { receiver !is Receiver.None } ?: "") +
identifier
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ sealed class SirFunction(
return "$identifierForReference($argumentsWithLabels)"
}

fun call(vararg arguments: String): String =
call(arguments.toList())

protected abstract val identifierForReference: String

override fun toString(): String = this.signature.toString()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ class SirValueParameter(
label = label
}

var label: String? = if (label != name) label else null
var label: String? = null
set(value) {
field = if (value != name && value?.isNotBlank() == true) value else null
}

init {
// Calls setter
this.label = label
}

val labelOrName: String
get() = label ?: name

Expand Down

0 comments on commit ff48e3a

Please sign in to comment.