@@ -67,6 +67,9 @@ internal class ModelQLExtensionsGenerator(
67
67
is ProcessedChildLink -> {
68
68
addChildGetter(feature)
69
69
addChildSetter(feature)
70
+ if (! feature.type.resolved.abstract) {
71
+ addDefaultChildSetter(feature)
72
+ }
70
73
}
71
74
72
75
is ProcessedReferenceLink -> {
@@ -81,7 +84,7 @@ internal class ModelQLExtensionsGenerator(
81
84
82
85
private fun FileSpec.Builder.addReferenceSetter (referenceLink : ProcessedReferenceLink ) {
83
86
val targetType = referenceLink.type.resolved.nodeWrapperInterfaceType().copy(nullable = referenceLink.optional)
84
- val inputStepType = IMonoStep :: class .asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType() )
87
+ val inputStepType = getSetterReceiverType( )
85
88
86
89
val parameterType = IMonoStep ::class .asTypeName().parameterizedBy(targetType)
87
90
.let { if (referenceLink.optional) it.copy(nullable = true ) else it }
@@ -162,26 +165,21 @@ internal class ModelQLExtensionsGenerator(
162
165
val targetType = childLink.type.resolved.nodeWrapperInterfaceType()
163
166
val outType = TypeVariableName (" Out" , targetType)
164
167
val returnType = IMonoStep ::class .asTypeName().parameterizedBy(outType)
165
- val receiverType = IMonoStep ::class .asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType())
166
- val conceptParameter = ParameterSpec .builder(" concept" , IConceptOfTypedNode ::class .asTypeName().parameterizedBy(outType)).apply {
167
- if (! childLink.type.resolved.abstract) {
168
- defaultValue(" %T" , childLink.type.resolved.conceptWrapperInterfaceClass())
169
- }
170
- }.build()
168
+ val receiverType = getSetterReceiverType()
169
+ val conceptParameter = ParameterSpec .builder(
170
+ name = " concept" ,
171
+ type = IConceptOfTypedNode ::class .asTypeName().parameterizedBy(outType),
172
+ ).build()
171
173
172
- val funName = if (childLink.multiple) childLink.adderMethodName() else childLink.setterName( )
174
+ val funName = getSetterName (childLink)
173
175
174
176
val funSpec = FunSpec .builder(funName).runBuild {
175
177
addTypeVariable(outType)
176
178
returns(returnType)
177
179
receiver(receiverType)
178
180
addParameter(conceptParameter)
179
181
if (childLink.multiple) {
180
- val indexParameter = ParameterSpec .builder(" index" , Int ::class .asTypeName())
181
- .defaultValue(" -1" )
182
- .build()
183
-
184
- addParameter(indexParameter)
182
+ addIndexParameter()
185
183
addStatement(
186
184
" return %T.addNewChild(this, %T.%N, index, concept)" ,
187
185
TypedModelQL ::class .asTypeName(),
@@ -201,6 +199,55 @@ internal class ModelQLExtensionsGenerator(
201
199
addFunction(funSpec)
202
200
}
203
201
202
+ /*
203
+ If we use the concept companion object as a default value for the concept parameter,
204
+ the kotlin compiler reports a type mismatch since it cannot properly infer the type variable.
205
+ That's why we need a separate default setter.
206
+ */
207
+ private fun FileSpec.Builder.addDefaultChildSetter (childLink : ProcessedChildLink ) {
208
+ val targetType = childLink.type.resolved.conceptWrapperInterfaceClass()
209
+ val returnType = IMonoStep ::class .asTypeName().parameterizedBy(childLink.type.resolved.nodeWrapperInterfaceType())
210
+ val receiverType = getSetterReceiverType()
211
+
212
+ val funName = getSetterName(childLink)
213
+
214
+ val funSpec = FunSpec .builder(funName).runBuild {
215
+ returns(returnType)
216
+ receiver(receiverType)
217
+ if (childLink.multiple) {
218
+ addIndexParameter()
219
+ addStatement(
220
+ " return %T.addNewChild(this, %T.%N, index, %T)" ,
221
+ TypedModelQL ::class .asTypeName(),
222
+ concept.conceptObjectType(),
223
+ childLink.generatedName,
224
+ targetType,
225
+ )
226
+ } else {
227
+ addStatement(
228
+ " return %T.setChild(this, %T.%N, %T)" ,
229
+ TypedModelQL ::class .asTypeName(),
230
+ concept.conceptObjectType(),
231
+ childLink.generatedName,
232
+ targetType,
233
+ )
234
+ }
235
+ }
236
+
237
+ addFunction(funSpec)
238
+ }
239
+
240
+ private fun FunSpec.Builder.addIndexParameter () {
241
+ val indexParameter = ParameterSpec .builder(" index" , Int ::class .asTypeName())
242
+ .defaultValue(" -1" )
243
+ .build()
244
+
245
+ addParameter(indexParameter)
246
+ }
247
+
248
+ private fun getSetterName (childLink : ProcessedChildLink ) =
249
+ if (childLink.multiple) childLink.adderMethodName() else childLink.setterName()
250
+
204
251
private fun FileSpec.Builder.addChildGetter (childLink : ProcessedChildLink ) {
205
252
val inputStepType = (if (childLink.multiple) IProducingStep ::class else IMonoStep ::class).asTypeName()
206
253
val outputStepType = (if (childLink.multiple) IFluxStep ::class else IMonoStep ::class).asTypeName()
@@ -228,8 +275,7 @@ internal class ModelQLExtensionsGenerator(
228
275
}
229
276
230
277
private fun FileSpec.Builder.addPropertySetter (property : ProcessedProperty ) {
231
- val inputStepType = IMonoStep ::class .asTypeName()
232
- .parameterizedBy(concept.nodeWrapperInterfaceType())
278
+ val inputStepType = getSetterReceiverType()
233
279
234
280
val parameterType = IMonoStep ::class .asTypeName()
235
281
.parameterizedBy(property.asKotlinType(alwaysUseNonNullableProperties))
@@ -249,6 +295,9 @@ internal class ModelQLExtensionsGenerator(
249
295
addFunction(setterSpec)
250
296
}
251
297
298
+ private fun getSetterReceiverType () =
299
+ IMonoStep ::class .asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType())
300
+
252
301
private fun FileSpec.Builder.addPropertyGetterForStepType (
253
302
property : ProcessedProperty ,
254
303
stepType : ClassName ,
0 commit comments