Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit 65f4844

Browse files
committed
fix: various issues with Python codegen of constructors
1 parent 112298e commit 65f4844

File tree

3 files changed

+26
-25
lines changed

3 files changed

+26
-25
lines changed

server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ private fun buildSeparators(
118118
fun PythonClass.toPythonCode(): String {
119119
var formattedClass = "class $name:\n"
120120
if (constructor != null) {
121-
formattedClass += buildConstructor().prependIndent(" ")
121+
formattedClass += buildConstructor(this).prependIndent(" ")
122122
}
123123
if (!methods.isEmpty()) {
124124
if (constructor != null) {
@@ -133,21 +133,24 @@ private fun buildAllFunctions(pythonClass: PythonClass): List<String> {
133133
return pythonClass.methods.map { it.toPythonCode().prependIndent(" ") }
134134
}
135135

136-
private fun PythonClass.buildConstructor(): String {
137-
var constructorSeparator = ""
138-
val assignments = buildAttributeAssignments(this).joinToString("\n".repeat(1))
139-
if (assignments.isNotBlank()) {
140-
constructorSeparator = "\n"
141-
}
142-
var constructorSuffix = constructorSeparator + assignments
143-
constructorSuffix += this.constructor?.buildConstructorCall() ?: ""
144-
if (constructorSuffix.isBlank()) {
145-
constructorSuffix = "pass"
136+
private fun buildConstructor(`class`: PythonClass) = buildString {
137+
appendLine("def __init__(${buildParameters(`class`.constructor?.parameters.orEmpty())}):")
138+
139+
appendIndented(4) {
140+
val attributes = buildAttributeAssignments(`class`).joinToString("\n")
141+
if (attributes.isNotBlank()) {
142+
append("$attributes\n\n")
143+
}
144+
145+
val constructorCall = `class`.constructor?.buildConstructorCall() ?: ""
146+
if (constructorCall.isNotBlank()) {
147+
append(constructorCall)
148+
}
149+
150+
if (attributes.isBlank() && constructorCall.isBlank()) {
151+
append("pass")
152+
}
146153
}
147-
return """
148-
|def __init__(${buildParameters(this.constructor?.parameters.orEmpty())}):
149-
|${(constructorSuffix).prependIndent(" ")}
150-
""".trimMargin()
151154
}
152155

153156
private fun PythonConstructor.buildConstructorCall(): String {

server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.larsreimann.api_editor.mutable_model.PythonFunction
1010
import com.larsreimann.api_editor.mutable_model.PythonPackage
1111
import com.larsreimann.api_editor.mutable_model.PythonParameter
1212
import com.larsreimann.api_editor.mutable_model.PythonReference
13+
import com.larsreimann.modeling.closest
1314
import com.larsreimann.modeling.descendants
1415

1516
/**
@@ -63,12 +64,16 @@ private fun PythonClass.addOriginalDeclarations() {
6364
}
6465

6566
private fun PythonFunction.addOriginalDeclarations() {
67+
val containingClass = closest<PythonClass>()
6668
this.callToOriginalAPI = PythonCall(
6769
receiver = when {
70+
name == "__init__" && containingClass != null -> containingClass.originalClass!!.qualifiedName
6871
isMethod() -> "self.instance.$name"
6972
else -> qualifiedName()
7073
},
71-
arguments = this.parameters.map {
74+
arguments = this.parameters
75+
.filter { !it.isImplicit() }
76+
.map {
7277
PythonArgument(
7378
name = when (it.assignedBy) {
7479
PythonParameterAssignment.NAME_ONLY -> it.name

server/src/test/kotlin/com/larsreimann/api_editor/transformation/PreprocessorTest.kt

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,13 @@ class PreprocessorTest {
181181
}
182182

183183
@Test
184-
fun `should add original declaration to class methods`() {
184+
fun `should add original declaration to class methods but skip implicit parameters`() {
185185
testPackage.addOriginalDeclarations()
186186

187187
val callToOriginalAPI = testMethod.callToOriginalAPI.shouldNotBeNull()
188188
callToOriginalAPI.receiver shouldBe "self.instance.testMethod"
189189

190-
val arguments = callToOriginalAPI.arguments
191-
arguments.shouldHaveSize(1)
192-
193-
arguments[0].name.shouldBeNull()
194-
arguments[0].value.asClue {
195-
it.shouldBeInstanceOf<PythonReference>()
196-
it.declaration shouldBe testMethodParameter
197-
}
190+
callToOriginalAPI.arguments.shouldHaveSize(0)
198191
}
199192
}
200193

0 commit comments

Comments
 (0)