From 59a1367f976825d354940011fa23794a1354b9d0 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Thu, 6 Jan 2022 20:08:20 +0100 Subject: [PATCH 1/7] feat: handle static methods in stub generator --- .../api_editor/codegen/StubCodeGenerator.kt | 1 + .../api_editor/codegen/StubCodeGeneratorTest.kt | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt index 8dd93c4ce..82bdc0948 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt @@ -135,6 +135,7 @@ internal fun MutablePythonFunction.toSmlFunction(): SmlFunction { return createSmlFunction( name = stubName, + isStatic = isStatic(), annotations = buildList { if (isPure) { add(createSmlAnnotationUse("Pure")) diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt index e4930a402..a96759b02 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt @@ -485,6 +485,7 @@ class StubCodeGeneratorTest { pythonFunction.toSmlFunction().asClue { it.name shouldBe "testFunction" + it.isStatic.shouldBeFalse() it.annotationUsesOrEmpty().shouldBeEmpty() it.typeParametersOrEmpty().shouldBeEmpty() it.parametersOrEmpty().shouldBeEmpty() @@ -493,6 +494,18 @@ class StubCodeGeneratorTest { } } + @Test + fun `should mark static methods with modifier`() { + val pythonFunction = MutablePythonFunction( + name = "testFunction", + decorators = mutableListOf("staticmethod") + ) + + pythonFunction.toSmlFunction().asClue { + it.isStatic.shouldBeTrue() + } + } + @Test fun `should mark pure functions with annotation`() { val pythonFunction = MutablePythonFunction( From 58bea495125b33e78a4394b22c85e7f786f240ef Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Thu, 6 Jan 2022 20:11:20 +0100 Subject: [PATCH 2/7] feat: store call to original API in constructor --- .../api_editor/mutable_model/PythonAst.kt | 3 +- .../transformation/Postprocessor.kt | 33 +++++++++++-- .../transformation/PostprocessorTest.kt | 46 +++++++++++++++++-- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt index 35960e286..ddffc9ac3 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt @@ -90,7 +90,8 @@ class MutablePythonClass( } class MutablePythonConstructor( - parameters: List = emptyList() + parameters: List = emptyList(), + val callToOriginalAPI: OriginalPythonFunction? = null ) : MutablePythonAstNode() { val parameters = MutableContainmentList(parameters) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Postprocessor.kt b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Postprocessor.kt index bfc1a9940..2092f85cc 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Postprocessor.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Postprocessor.kt @@ -6,6 +6,7 @@ import com.larsreimann.api_editor.mutable_model.MutablePythonClass import com.larsreimann.api_editor.mutable_model.MutablePythonConstructor import com.larsreimann.api_editor.mutable_model.MutablePythonFunction import com.larsreimann.api_editor.mutable_model.MutablePythonPackage +import com.larsreimann.api_editor.mutable_model.OriginalPythonFunction import com.larsreimann.api_editor.mutable_model.descendants /** @@ -51,12 +52,36 @@ fun MutablePythonPackage.createConstructors() { } private fun MutablePythonClass.createConstructor() { - this.constructor = MutablePythonConstructor() + when (val constructorMethod = this.methods.firstOrNull { it.name == "__init__" }) { + null -> { + this.constructor = MutablePythonConstructor( + parameters = emptyList(), + callToOriginalAPI = OriginalPythonFunction( + qualifiedName = this.qualifiedName() + ) + ) + } + else -> { + val qualifiedName = constructorMethod.originalFunction + ?.qualifiedName + ?.removeSuffix(".__init__") + ?: qualifiedName() - val constructorMethod = this.methods.firstOrNull { it.name == "__init__" } ?: return + val parameters = constructorMethod.originalFunction + ?.parameters + ?: emptyList() - this.constructor?.parameters?.addAll(constructorMethod.parameters.toList()) - constructorMethod.release() + this.constructor = MutablePythonConstructor( + parameters = constructorMethod.parameters.toList(), + callToOriginalAPI = OriginalPythonFunction( + qualifiedName = qualifiedName, + parameters = parameters + ) + ) + + constructorMethod.release() + } + } } /** diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PostprocessorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PostprocessorTest.kt index 6dd449170..f8c0deed2 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PostprocessorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PostprocessorTest.kt @@ -7,6 +7,9 @@ import com.larsreimann.api_editor.mutable_model.MutablePythonFunction import com.larsreimann.api_editor.mutable_model.MutablePythonModule import com.larsreimann.api_editor.mutable_model.MutablePythonPackage import com.larsreimann.api_editor.mutable_model.MutablePythonParameter +import com.larsreimann.api_editor.mutable_model.OriginalPythonFunction +import com.larsreimann.api_editor.mutable_model.OriginalPythonParameter +import io.kotest.assertions.asClue import io.kotest.matchers.collections.exist import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldContain @@ -14,6 +17,7 @@ import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldExist import io.kotest.matchers.collections.shouldNotContain import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNot import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested @@ -50,7 +54,16 @@ class PostprocessorTest { MutablePythonFunction( name = "__init__", parameters = listOf( - MutablePythonParameter(name = "constructorParameter") + MutablePythonParameter( + name = "constructorParameter", + originalParameter = OriginalPythonParameter(name = "constructorParameter") + ) + ), + originalFunction = OriginalPythonFunction( + qualifiedName = "testModule.TestClass.__init__", + parameters = listOf( + OriginalPythonParameter(name = "constructorParameter") + ) ) ) ) @@ -154,9 +167,13 @@ class PostprocessorTest { testPackage.createConstructors() testClass.constructor - .shouldNotBeNull() - .parameters - .shouldBeEmpty() + .shouldNotBeNull().asClue { + it.parameters.shouldBeEmpty() + it.callToOriginalAPI shouldBe OriginalPythonFunction( + qualifiedName = "testModule.TestClass", + parameters = emptyList() + ) + } } @Test @@ -172,6 +189,27 @@ class PostprocessorTest { .shouldContainExactly("constructorParameter") } + @Test + fun `should store call to original API`() { + testClass.constructor = null + + testPackage.createConstructors() + + testClass.constructor + .shouldNotBeNull() + .callToOriginalAPI + .shouldBe( + OriginalPythonFunction( + qualifiedName = "testModule.TestClass", + parameters = listOf( + OriginalPythonParameter( + name = "constructorParameter" + ) + ) + ) + ) + } + @Test fun `should remove __init__ methods`() { testClass.constructor = null From b7c3f48abaffe2637a312c917a0051e60111b212 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Thu, 6 Jan 2022 20:11:54 +0100 Subject: [PATCH 3/7] test: update tests of Python codegen --- .../codegen/PythonCodeGeneratorTest.kt | 49 +++++++++++++++++-- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt index 3e445b7e6..8084ce693 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt @@ -152,7 +152,7 @@ class PythonCodeGeneratorTest { | |class test-class: | def test-class-function(self, *, only-param='defaultValue'): - | test-module.test-class.test-class-function(only-param) + | self.instance.test-class-function(only-param) | |def function_module(param1, param2, param3): | test-module.function_module(param1=param1, param2=param2, param3=param3) @@ -573,7 +573,7 @@ class PythonCodeGeneratorTest { """ |class test-class: | def __init__(self, *, only-param='defaultValue'): - | test-module.test-class.__init__(only-param) + | self.instance = test-module.test-class(only-param) """.trimMargin() formattedClass shouldBe expectedFormattedClass } @@ -651,10 +651,10 @@ class PythonCodeGeneratorTest { """ |class test-class: | def test-class-function1(self, only-param): - | test-module.test-class.test-class-function1(only-param) + | self.instance.test-class-function1(only-param) | | def test-class-function2(self, only-param): - | test-module.test-class.test-class-function2(only-param)""".trimMargin() + | self.instance.test-class-function2(only-param)""".trimMargin() formattedClass shouldBe expectedFormattedClass } @@ -713,7 +713,7 @@ class PythonCodeGeneratorTest { """ |class test-class: | def test-function(self, second-param, third-param): - | test-module.test-class.test-function(second-param, third-param=third-param)""".trimMargin() + | self.instance.test-function(second-param, third-param=third-param)""".trimMargin() formattedClass shouldBe expectedFormattedClass } @@ -1048,4 +1048,43 @@ class PythonCodeGeneratorTest { | test-module.test-function(first-param, second-param, third-param=third-param)""".trimMargin() formattedFunction shouldBe expectedFormattedFunction } + + @Test + fun buildClassReturnsFormattedClassWithStaticMethodDecorator() { + // given + val testClass = MutablePythonClass( + name = "test-class", + methods = listOf( + MutablePythonFunction( + name = "test-class-function1", + decorators = mutableListOf("staticmethod"), + parameters = listOf( + MutablePythonParameter( + name = "only-param", + originalParameter = OriginalPythonParameter(name = "only-param") + ) + ), + originalFunction = OriginalPythonFunction( + qualifiedName = "test-module.test-class.test-class-function1", + parameters = listOf( + OriginalPythonParameter(name = "only-param") + ) + ) + ) + ) + ) + + // when + val formattedClass: String = testClass.toPythonCode() + + // then + val expectedFormattedClass: String = + """ + |class test-class: + | @staticmethod + | def test-class-function1(only-param): + | test-module.test-class.test-class-function1(only-param)""".trimMargin() + + formattedClass shouldBe expectedFormattedClass + } } From 6adfac4748b6370e47b35aba44bb43243fc39203 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Thu, 6 Jan 2022 20:22:29 +0100 Subject: [PATCH 4/7] feat: normalize names of implicit parameters --- .../api_editor/transformation/Preprocessor.kt | 12 ++++++++++++ .../transformation/TransformationPlan.kt | 2 ++ .../transformation/PreprocessorTest.kt | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt index 0c9ea3bfa..a3a0dbb40 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt @@ -141,3 +141,15 @@ private fun MutablePythonParameter.isImplicit(): Boolean { !currentFunction.isStatic() && currentFunction.parameters.firstOrNull() == this } + +/** + * Changes the name of implicit parameters to "self". + */ +fun MutablePythonPackage.normalizeNamesOfImplicitParameters() { + this.descendants() + .filterIsInstance() + .filter { it.assignedBy == PythonParameterAssignment.IMPLICIT } + .forEach { + it.name = "self" + } +} diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/TransformationPlan.kt b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/TransformationPlan.kt index 2e2e1447e..2c083c91b 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/TransformationPlan.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/TransformationPlan.kt @@ -20,6 +20,7 @@ private fun MutablePythonPackage.preprocess() { changeModulePrefix(newPrefix = "simpleml") replaceClassMethodsWithStaticMethods() updateParameterAssignment() + normalizeNamesOfImplicitParameters() } /** @@ -40,5 +41,6 @@ private fun MutablePythonPackage.processAnnotations() { private fun MutablePythonPackage.postprocess() { removeEmptyModules() reorderParameters() + createConstructors() createAttributesForParametersOfConstructor() } diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PreprocessorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PreprocessorTest.kt index 1a403d0de..4bc1fd947 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PreprocessorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/transformation/PreprocessorTest.kt @@ -252,4 +252,23 @@ class PreprocessorTest { testOptionalParameter.assignedBy shouldBe PythonParameterAssignment.NAME_ONLY } } + + @Nested + inner class NormalizeNamesOfImplicitParameters { + + @Test + fun `should change the name of implicit parameters to 'self'`() { + testMethodParameter.assignedBy = PythonParameterAssignment.IMPLICIT + testPackage.normalizeNamesOfImplicitParameters() + + testMethodParameter.name shouldBe "self" + } + + @Test + fun `should not change name of non-implicit parameters`() { + testPackage.normalizeNamesOfImplicitParameters() + + testRequiredParameter.name shouldBe "testRequiredParameter" + } + } } From f17cd47c4a103fd5c224521335a02b531f0f443a Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Fri, 7 Jan 2022 16:03:21 +0100 Subject: [PATCH 5/7] feat: update Python codegen --- .../api_editor/codegen/PythonCodeGenerator.kt | 55 ++++++++++++-- .../api_editor/codegen/StubCodeGenerator.kt | 2 +- .../api_editor/mutable_model/PythonAst.kt | 3 +- .../api_editor/transformation/Preprocessor.kt | 2 +- .../codegen/PythonCodeGeneratorTest.kt | 71 ++++++++++--------- .../codegen/StubCodeGeneratorTest.kt | 4 ++ 6 files changed, 94 insertions(+), 43 deletions(-) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt index d7a5d8a2e..b69749197 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt @@ -3,9 +3,11 @@ package com.larsreimann.api_editor.codegen import com.larsreimann.api_editor.model.ComparisonOperator import com.larsreimann.api_editor.model.PythonParameterAssignment import com.larsreimann.api_editor.mutable_model.MutablePythonClass +import com.larsreimann.api_editor.mutable_model.MutablePythonConstructor import com.larsreimann.api_editor.mutable_model.MutablePythonFunction import com.larsreimann.api_editor.mutable_model.MutablePythonModule import com.larsreimann.api_editor.mutable_model.MutablePythonParameter +import com.larsreimann.api_editor.mutable_model.OriginalPythonParameter /** * Builds a string containing the formatted module content @@ -117,6 +119,7 @@ private fun MutablePythonClass.buildConstructor(): String { constructorSeparator = "\n" } var constructorSuffix = constructorSeparator + assignments + constructorSuffix += this.constructor?.buildConstructorCall() ?: "" if (constructorSuffix.isBlank()) { constructorSuffix = "pass" } @@ -126,16 +129,25 @@ private fun MutablePythonClass.buildConstructor(): String { """.trimMargin() } +private fun MutablePythonConstructor.buildConstructorCall(): String { + return "self.instance = ${callToOriginalAPI!!.qualifiedName}(${this.buildParameterCall()})" +} + /** * Builds a string containing the formatted function content * @receiver The function whose adapter content should be built * @return The string containing the formatted function content */ fun MutablePythonFunction.toPythonCode(): String { - return """ + val function = """ |def $name(${buildParameters(this.parameters)}): |${(buildFunctionBody(this)).prependIndent(" ")} """.trimMargin() + + return when { + isStaticMethod() -> "@staticmethod\n$function" + else -> function + } } private fun buildAttributeAssignments(pythonClass: MutablePythonClass): List { @@ -204,13 +216,26 @@ private fun buildFunctionBody(pythonFunction: MutablePythonFunction): String { if (formattedBoundaries.isNotBlank()) { formattedBoundaries = "$formattedBoundaries\n" } + + if (!pythonFunction.isMethod() || pythonFunction.isStaticMethod()) { + return ( + formattedBoundaries + + pythonFunction.originalFunction!!.qualifiedName + + "(" + + pythonFunction.buildParameterCall() + + ")" + ) + } + return ( formattedBoundaries + - pythonFunction.originalFunction!!.qualifiedName + + "self.instance." + + pythonFunction.originalFunction!!.qualifiedName.split(".").last() + "(" + - buildParameterCall(pythonFunction) + + pythonFunction.buildParameterCall() + ")" ) + } private fun buildBoundaryChecks(pythonFunction: MutablePythonFunction): List { @@ -297,10 +322,28 @@ private fun buildBoundaryChecks(pythonFunction: MutablePythonFunction): List, + originalParameters: List +): String { + val formattedParameters: MutableList = ArrayList() val originalNameToValueMap: MutableMap = HashMap() - pythonFunction.parameters.forEach { + parameters.forEach { val value: String? = if (it.assignedBy == PythonParameterAssignment.CONSTANT || it.assignedBy == PythonParameterAssignment.ATTRIBUTE) { it.defaultValue @@ -309,7 +352,7 @@ private fun buildParameterCall(pythonFunction: MutablePythonFunction): String { } originalNameToValueMap[it.originalParameter!!.name] = value } - pythonFunction.originalFunction!!.parameters + originalParameters .filter { it.assignedBy != PythonParameterAssignment.IMPLICIT } .forEach { if (it.assignedBy === PythonParameterAssignment.NAME_ONLY) { diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt index 82bdc0948..aeb2f1b1d 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/StubCodeGenerator.kt @@ -135,7 +135,7 @@ internal fun MutablePythonFunction.toSmlFunction(): SmlFunction { return createSmlFunction( name = stubName, - isStatic = isStatic(), + isStatic = isStaticMethod(), annotations = buildList { if (isPure) { add(createSmlAnnotationUse("Pure")) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt index ddffc9ac3..f42de35f1 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/PythonAst.kt @@ -142,7 +142,8 @@ class MutablePythonFunction( yieldAll(results) } - fun isStatic() = "staticmethod" in decorators + fun isMethod() = parent is MutablePythonClass + fun isStaticMethod() = isMethod() && "staticmethod" in decorators } data class OriginalPythonFunction( diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt index a3a0dbb40..85f63bad4 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/transformation/Preprocessor.kt @@ -138,7 +138,7 @@ private fun MutablePythonParameter.updateParameterAssignment() { private fun MutablePythonParameter.isImplicit(): Boolean { val currentFunction = this.parent as? MutablePythonFunction ?: return false return currentFunction.parent is MutablePythonClass && - !currentFunction.isStatic() && + !currentFunction.isStaticMethod() && currentFunction.parameters.firstOrNull() == this } diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt index 8084ce693..bb9161bf6 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGeneratorTest.kt @@ -280,7 +280,9 @@ class PythonCodeGeneratorTest { // given val testClass = MutablePythonClass( name = "test-class", - constructor = MutablePythonConstructor(), + constructor = MutablePythonConstructor( + callToOriginalAPI = OriginalPythonFunction(qualifiedName = "test-class") + ), originalClass = OriginalPythonClass("test-module.test-class") ) val testModule = MutablePythonModule( @@ -311,7 +313,7 @@ class PythonCodeGeneratorTest { | |class test-class: | def __init__(): - | pass + | self.instance = test-class() | """.trimMargin() @@ -510,13 +512,17 @@ class PythonCodeGeneratorTest { fun `should create valid code for empty classes`() { // TODO val testClass = MutablePythonClass( name = "TestClass", - constructor = MutablePythonConstructor() + constructor = MutablePythonConstructor( + callToOriginalAPI = OriginalPythonFunction( + qualifiedName = "TestClass" + ) + ) ) testClass.toPythonCode() shouldBe """ |class TestClass: | def __init__(): - | pass + | self.instance = TestClass() """.trimMargin() } @@ -525,39 +531,36 @@ class PythonCodeGeneratorTest { // given val testClass = MutablePythonClass( name = "test-class", - methods = mutableListOf( - MutablePythonFunction( - name = "__init__", - parameters = mutableListOf( - MutablePythonParameter( + constructor = MutablePythonConstructor( + parameters = mutableListOf( + MutablePythonParameter( + name = "self", + assignedBy = PythonParameterAssignment.IMPLICIT, + originalParameter = OriginalPythonParameter( name = "self", - assignedBy = PythonParameterAssignment.IMPLICIT, - originalParameter = OriginalPythonParameter( - name = "self", - assignedBy = PythonParameterAssignment.IMPLICIT - ) - ), - MutablePythonParameter( - name = "only-param", - defaultValue = "'defaultValue'", - assignedBy = PythonParameterAssignment.NAME_ONLY, - originalParameter = OriginalPythonParameter( - name = "only-param", - assignedBy = PythonParameterAssignment.POSITION_OR_NAME - ) + assignedBy = PythonParameterAssignment.IMPLICIT ) ), - originalFunction = OriginalPythonFunction( - qualifiedName = "test-module.test-class.__init__", - parameters = listOf( - OriginalPythonParameter( - name = "self", - assignedBy = PythonParameterAssignment.IMPLICIT - ), - OriginalPythonParameter( - name = "only-param", - assignedBy = PythonParameterAssignment.POSITION_OR_NAME - ) + MutablePythonParameter( + name = "only-param", + defaultValue = "'defaultValue'", + assignedBy = PythonParameterAssignment.NAME_ONLY, + originalParameter = OriginalPythonParameter( + name = "only-param", + assignedBy = PythonParameterAssignment.POSITION_OR_NAME + ) + ) + ), + callToOriginalAPI = OriginalPythonFunction( + qualifiedName = "test-module.test-class", + parameters = listOf( + OriginalPythonParameter( + name = "self", + assignedBy = PythonParameterAssignment.IMPLICIT + ), + OriginalPythonParameter( + name = "only-param", + assignedBy = PythonParameterAssignment.POSITION_OR_NAME ) ) ) diff --git a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt index a96759b02..617a94c68 100644 --- a/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt +++ b/server/src/test/kotlin/com/larsreimann/api_editor/codegen/StubCodeGeneratorTest.kt @@ -500,6 +500,10 @@ class StubCodeGeneratorTest { name = "testFunction", decorators = mutableListOf("staticmethod") ) + MutablePythonClass( + name = "TestClass", + methods = listOf(pythonFunction) + ) pythonFunction.toSmlFunction().asClue { it.isStatic.shouldBeTrue() From 4ab2aedfc62d6e6c0ca1d681763cb887b8138f33 Mon Sep 17 00:00:00 2001 From: lars-reimann Date: Fri, 7 Jan 2022 15:14:15 +0000 Subject: [PATCH 6/7] style: apply automatic fixes of linters --- .../com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt index b69749197..87230cb90 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/codegen/PythonCodeGenerator.kt @@ -235,7 +235,6 @@ private fun buildFunctionBody(pythonFunction: MutablePythonFunction): String { pythonFunction.buildParameterCall() + ")" ) - } private fun buildBoundaryChecks(pythonFunction: MutablePythonFunction): List { From 68b6c51e8694308802ffc951f2a06c8acedb7446 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Fri, 7 Jan 2022 16:15:31 +0100 Subject: [PATCH 7/7] fix: wrong type on getValue and setValue --- .../com/larsreimann/api_editor/mutable_model/Node.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/Node.kt b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/Node.kt index 9a63b2d3e..b08f1a250 100644 --- a/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/Node.kt +++ b/server/src/main/kotlin/com/larsreimann/api_editor/mutable_model/Node.kt @@ -181,11 +181,11 @@ open class Node { } } - operator fun getValue(node: Node, property: KProperty<*>): T? { + operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { return this.node } - operator fun setValue(oldNode: Node, property: KProperty<*>, newNode: T?) { + operator fun setValue(thisRef: Any?, property: KProperty<*>, newNode: T?) { this.node = newNode } } @@ -382,11 +382,11 @@ open class Node { handleMove(from, to) } - operator fun getValue(node: T, property: KProperty<*>): T? { + operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { return this.node } - operator fun setValue(oldNode: T, property: KProperty<*>, newNode: T?) { + operator fun setValue(thisRef: Any?, property: KProperty<*>, newNode: T?) { this.node = newNode } }