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

Commit f5e6a7d

Browse files
authored
feat: todo annotation for parameters (#793)
* feat(gui): allow adding todo annotations to parameters * test(backend): failing codegen tests * feat(backend): codegen for todo comments of parameters * feat(backend): process todo annotations on parameters
1 parent 5e70ce1 commit f5e6a7d

File tree

5 files changed

+50
-13
lines changed

5 files changed

+50
-13
lines changed

api-editor/backend/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fun PythonClass.toPythonCode() = buildString {
147147
}
148148

149149
fun PythonConstructor.toPythonCode() = buildString {
150-
val todoComment = todoComment(todo)
150+
val todoComments = listOf(todoComment(todo)) + parameters.map { todoComment(it.todo, "param:${it.name}") }
151151
val parametersString = parameters.toPythonCode()
152152
val boundariesString = parameters
153153
.mapNotNull { it.boundary?.toPythonCode(it.name) }
@@ -160,8 +160,10 @@ fun PythonConstructor.toPythonCode() = buildString {
160160
?.let { "self.instance = ${it.toPythonCode()}" }
161161
?: ""
162162

163-
if (todoComment.isNotBlank()) {
164-
appendLine(todoComment)
163+
todoComments.forEach {
164+
if (it.isNotBlank()) {
165+
appendLine(it)
166+
}
165167
}
166168
appendLine("def __init__($parametersString):")
167169
if (boundariesString.isNotBlank()) {
@@ -210,7 +212,7 @@ fun PythonEnumInstance.toPythonCode(enumName: String): String {
210212
}
211213

212214
fun PythonFunction.toPythonCode() = buildString {
213-
val todoComment = todoComment(todo)
215+
val todoComments = listOf(todoComment(todo)) + parameters.map { todoComment(it.todo, "param:${it.name}") }
214216
val parametersString = parameters.toPythonCode()
215217
val docstring = docstring()
216218
val boundariesString = parameters
@@ -220,8 +222,10 @@ fun PythonFunction.toPythonCode() = buildString {
220222
?.let { "return ${it.toPythonCode()}" }
221223
?: ""
222224

223-
if (todoComment.isNotBlank()) {
224-
appendLine(todoComment)
225+
todoComments.forEach {
226+
if (it.isNotBlank()) {
227+
appendLine(it)
228+
}
225229
}
226230
if (isStaticMethod()) {
227231
appendLine("@staticmethod")
@@ -328,6 +332,7 @@ fun PythonType?.toPythonCodeOrNull(): String? {
328332
else -> null
329333
}
330334
}
335+
331336
null -> null
332337
}
333338
}
@@ -370,7 +375,7 @@ fun Boundary.toPythonCode(parameterName: String) = buildString {
370375
}
371376
}
372377

373-
fun todoComment(message: String) = buildString {
378+
fun todoComment(message: String, scope: String = "") = buildString {
374379
if (message.isBlank()) {
375380
return ""
376381
}
@@ -379,7 +384,12 @@ fun todoComment(message: String) = buildString {
379384
val firstLine = lines.first()
380385
val remainingLines = lines.drop(1)
381386

382-
appendLine("# TODO: ${firstLine.trim()}")
387+
append("# TODO")
388+
if (scope.isNotBlank()) {
389+
append("($scope)")
390+
}
391+
appendLine(": ${firstLine.trim()}")
392+
383393
remainingLines.forEachIndexed { index, line ->
384394
val indentedLine = "# $line"
385395
append(indentedLine.trim())

api-editor/backend/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class PythonParameter(
188188
defaultValue: PythonExpression? = null,
189189
var assignedBy: PythonParameterAssignment = PythonParameterAssignment.POSITION_OR_NAME,
190190
var description: String = "",
191+
var todo: String = "",
191192
var boundary: Boundary? = null,
192193
override val annotations: MutableList<EditorAnnotation> = mutableListOf(),
193194
) : PythonDeclaration() {

api-editor/backend/src/main/kotlin/com/larsreimann/api_editor/transformation/TodoAnnotationProcessor.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.larsreimann.api_editor.mutable_model.PythonClass
55
import com.larsreimann.api_editor.mutable_model.PythonDeclaration
66
import com.larsreimann.api_editor.mutable_model.PythonFunction
77
import com.larsreimann.api_editor.mutable_model.PythonPackage
8+
import com.larsreimann.api_editor.mutable_model.PythonParameter
89
import com.larsreimann.modeling.descendants
910

1011
/**
@@ -23,6 +24,7 @@ private fun PythonDeclaration.processTodoAnnotations() {
2324
when (this) {
2425
is PythonClass -> this.todo = it.message
2526
is PythonFunction -> this.todo = it.message
27+
is PythonParameter -> this.todo = it.message
2628
else -> {
2729
// Do nothing
2830
}

api-editor/backend/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,15 +462,29 @@ class PythonCodeGeneratorTest {
462462
@Test
463463
fun `should store todo if it is not blank`() {
464464
val testConstructor = PythonConstructor(
465-
todo = " Lorem ipsum\n\n Dolor sit\namet\n"
465+
todo = " Lorem ipsum\n\n Dolor sit\namet\n",
466+
parameters = listOf(
467+
PythonParameter(
468+
name = "self",
469+
assignedBy = PythonParameterAssignment.IMPLICIT
470+
),
471+
PythonParameter(
472+
name = "unfinished",
473+
todo = " Lorem ipsum\n\n Dolor sit\namet\n",
474+
),
475+
)
466476
)
467477

468478
testConstructor.toPythonCode() shouldBe """
469479
|# TODO: Lorem ipsum
470480
|#
471481
|# Dolor sit
472482
|# amet
473-
|def __init__():
483+
|# TODO(param:unfinished): Lorem ipsum
484+
|#
485+
|# Dolor sit
486+
|# amet
487+
|def __init__(self, unfinished):
474488
| pass
475489
""".trimMargin()
476490
}
@@ -725,23 +739,32 @@ class PythonCodeGeneratorTest {
725739
fun `should store todo if it is not blank`() {
726740
val testFunction = PythonFunction(
727741
name = "testFunction",
728-
todo = " Lorem ipsum\n\n Dolor sit\namet\n"
742+
todo = " Lorem ipsum\n\n Dolor sit\namet\n",
743+
parameters = listOf(
744+
PythonParameter(
745+
name = "unfinished",
746+
todo = " Lorem ipsum\n\n Dolor sit\namet\n",
747+
),
748+
)
729749
)
730750

731751
testFunction.toPythonCode() shouldBe """
732752
|# TODO: Lorem ipsum
733753
|#
734754
|# Dolor sit
735755
|# amet
736-
|def testFunction():
756+
|# TODO(param:unfinished): Lorem ipsum
757+
|#
758+
|# Dolor sit
759+
|# amet
760+
|def testFunction(unfinished):
737761
| pass
738762
""".trimMargin()
739763
}
740764
}
741765

742766
@Nested
743767
inner class ModuleToPythonCode {
744-
745768
private lateinit var testModule: PythonModule
746769
private lateinit var testClasses: List<PythonClass>
747770
private lateinit var testFunctions: List<PythonFunction>

api-editor/gui/src/features/packageData/selectionView/ParameterNode.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const ParameterNode: React.FC<ParameterNodeProps> = function ({ isTitle,
4444
showOptional
4545
showRename
4646
showRequired
47+
showTodo
4748
/>
4849
)}
4950
<CompleteButton target={id} />

0 commit comments

Comments
 (0)