Skip to content

Commit 1be20c2

Browse files
committed
fix(modelql): return the concept type instead of the link type after node creation steps
1 parent 3c161d3 commit 1be20c2

File tree

3 files changed

+21
-7
lines changed

3 files changed

+21
-7
lines changed

model-api-gen-gradle-test/kotlin-generation/src/test/kotlin/org/modelix/modelql/typed/TypedModelQLTest.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,15 @@ abstract class TypedModelQLTest {
360360

361361
assertTrue { actual.instanceOf(C_XmlDocument) }
362362
}
363+
364+
@Test
365+
fun `write operations return typed nodes`() = runTest { client ->
366+
val name = client.query { root ->
367+
root.children("classes").ofConcept(C_ClassConcept)
368+
.first()
369+
.addToMember(C_StaticMethodDeclaration)
370+
.name
371+
}
372+
assertEquals("", name)
373+
}
363374
}

model-api-gen/src/main/kotlin/org/modelix/metamodel/generator/internal/ModelQLExtensionsGenerator.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ import com.squareup.kotlinpoet.ParameterSpec
2323
import com.squareup.kotlinpoet.ParameterizedTypeName
2424
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
2525
import com.squareup.kotlinpoet.PropertySpec
26+
import com.squareup.kotlinpoet.TypeVariableName
2627
import com.squareup.kotlinpoet.asTypeName
27-
import org.modelix.metamodel.ITypedConcept
28+
import org.modelix.metamodel.IConceptOfTypedNode
2829
import org.modelix.metamodel.generator.MetaModelGenerator
2930
import org.modelix.metamodel.generator.NameConfig
3031
import org.modelix.metamodel.generator.ProcessedChildLink
@@ -159,9 +160,10 @@ internal class ModelQLExtensionsGenerator(
159160

160161
private fun FileSpec.Builder.addChildSetter(childLink: ProcessedChildLink) {
161162
val targetType = childLink.type.resolved.nodeWrapperInterfaceType()
162-
val returnType = IMonoStep::class.asTypeName().parameterizedBy(targetType)
163+
val outType = TypeVariableName("Out", targetType)
164+
val returnType = IMonoStep::class.asTypeName().parameterizedBy(outType)
163165
val receiverType = IMonoStep::class.asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType())
164-
val conceptParameter = ParameterSpec.builder("concept", ITypedConcept::class.asTypeName()).apply {
166+
val conceptParameter = ParameterSpec.builder("concept", IConceptOfTypedNode::class.asTypeName().parameterizedBy(outType)).apply {
165167
if (!childLink.type.resolved.abstract) {
166168
defaultValue("%T", childLink.type.resolved.conceptWrapperInterfaceClass())
167169
}
@@ -170,6 +172,7 @@ internal class ModelQLExtensionsGenerator(
170172
val funName = if (childLink.multiple) childLink.adderMethodName() else childLink.setterName()
171173

172174
val funSpec = FunSpec.builder(funName).runBuild {
175+
addTypeVariable(outType)
173176
returns(returnType)
174177
receiver(receiverType)
175178
addParameter(conceptParameter)

modelql-typed/src/commonMain/kotlin/org/modelix/modelql/typed/TypedModelQL.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ object TypedModelQL {
144144
return input.untyped().flatMap { it.children(link.untyped().key()) }.typedUnsafe(link.getTypedChildConcept().getInstanceInterface())
145145
}
146146

147-
fun <ParentT : ITypedNode, ChildT : ITypedNode> addNewChild(input: IMonoStep<ParentT>, link: ITypedChildListLink<ChildT>, index: Int = -1, concept: ITypedConcept): IMonoStep<ChildT> {
147+
fun <ParentT : ITypedNode, ChildT : ITypedNode, Out : ChildT> addNewChild(input: IMonoStep<ParentT>, link: ITypedChildListLink<ChildT>, index: Int = -1, concept: IConceptOfTypedNode<Out>): IMonoStep<Out> {
148148
val conceptRef = ConceptReference(concept.untyped().getUID())
149-
return input.untyped().addNewChild(link.untyped(), index, conceptRef).typedUnsafe(link.getTypedChildConcept().getInstanceInterface())
149+
return input.untyped().addNewChild(link.untyped(), index, conceptRef).ofConcept(concept)
150150
}
151151

152-
fun <ParentT : ITypedNode, ChildT : ITypedNode> setChild(input: IMonoStep<ParentT>, link: ITypedSingleChildLink<ChildT>, concept: ITypedConcept): IMonoStep<ChildT> {
152+
fun <ParentT : ITypedNode, ChildT : ITypedNode, Out : ChildT> setChild(input: IMonoStep<ParentT>, link: ITypedSingleChildLink<ChildT>, concept: IConceptOfTypedNode<Out>): IMonoStep<Out> {
153153
val conceptRef = ConceptReference(concept.untyped().getUID())
154154
input.untyped().children(link.untyped().key()).firstOrNull().mapIfNotNull { it.remove() }
155-
return input.untyped().addNewChild(link.untyped(), conceptRef).typedUnsafe(link.getTypedChildConcept().getInstanceInterface())
155+
return input.untyped().addNewChild(link.untyped(), conceptRef).ofConcept(concept)
156156
}
157157

158158
fun <SourceT : ITypedNode, TargetT : ITypedNode> reference(input: IMonoStep<SourceT>, link: ITypedReferenceLink<TargetT>): IMonoStep<TargetT> {

0 commit comments

Comments
 (0)