Skip to content

Commit d9a7847

Browse files
committed
typed concepts are generated with default implementations instead impl classes
This simplifies the generated code a lot. There no inheritance between the impl classes anymore. The implementation of the members is not inherited through multiple inheritance paths so no ambiguity that needs to be solved.
1 parent 093f1a6 commit d9a7847

File tree

2 files changed

+26
-60
lines changed

2 files changed

+26
-60
lines changed

metamodel-generator/src/main/kotlin/org/modelix/metamodel/generator/MetaModelGenerator.kt

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class MetaModelGenerator(val outputDir: Path) {
9393
.addFileComment(headerComment)
9494
.addType(generateConceptObject(concept))
9595
.addType(generateConceptWrapperInterface(concept))
96-
.addType(generateConceptWrapperImpl(concept))
96+
// .addType(generateConceptWrapperImpl(concept))
9797
.addType(generateNodeWrapperInterface(concept))
9898
.addType(generateNodeWrapperImpl(concept))
9999
.apply {
@@ -139,8 +139,8 @@ class MetaModelGenerator(val outputDir: Path) {
139139
private fun generateConceptObject(concept: LanguageSet.ConceptInLanguage): TypeSpec {
140140
return TypeSpec.objectBuilder(concept.conceptObjectName()).apply {
141141
superclass(GeneratedConcept::class.asTypeName().parameterizedBy(
142-
concept.nodeWrapperImplType(),
143-
concept.conceptWrapperImplType()
142+
concept.nodeWrapperInterfaceType(),
143+
concept.conceptWrapperInterfaceType()
144144
))
145145
addSuperclassConstructorParameter("%S", concept.concept.name)
146146
addSuperclassConstructorParameter(concept.concept.abstract.toString())
@@ -226,74 +226,40 @@ class MetaModelGenerator(val outputDir: Path) {
226226
}
227227
for (feature in concept.directFeatures()) {
228228
when (val data = feature.data) {
229-
is PropertyData -> addProperty(PropertySpec.builder(feature.validName, GeneratedProperty::class.asClassName().parameterizedBy(data.asKotlinType())).build())
230-
is ChildLinkData -> addProperty(PropertySpec.builder(feature.validName, feature.generatedChildLinkType()).build())
231-
is ReferenceLinkData -> addProperty(PropertySpec.builder(feature.validName, feature.generatedReferenceLinkType()).build())
229+
is PropertyData -> addProperty(PropertySpec.builder(feature.validName, GeneratedProperty::class.asClassName().parameterizedBy(data.asKotlinType()))
230+
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
231+
.build())
232+
is ChildLinkData -> addProperty(PropertySpec.builder(feature.validName, feature.generatedChildLinkType())
233+
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
234+
.build())
235+
is ReferenceLinkData -> addProperty(PropertySpec.builder(feature.validName, feature.generatedReferenceLinkType())
236+
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
237+
.build())
232238
}
233239
}
234240

235241
addType(TypeSpec.companionObjectBuilder().apply {
236-
superclass(concept.conceptWrapperImplType())
242+
addSuperinterface(concept.conceptWrapperInterfaceType())
237243
val t = if (concept.concept.abstract) IConceptOfTypedNode::class else INonAbstractConcept::class
238244
addSuperinterface(t.asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType()))
239245
addFunction(FunSpec.builder(IConceptOfTypedNode<*>::getInstanceInterface.name)
240246
.addModifiers(KModifier.OVERRIDE)
241247
.returns(KClass::class.asTypeName().parameterizedBy(concept.nodeWrapperInterfaceType()))
242248
.addStatement("return %T::class", concept.nodeWrapperInterfaceType())
243249
.build())
250+
addFunction(FunSpec.builder(ITypedConcept::untyped.name)
251+
.returns(IConcept::class)
252+
.addModifiers(KModifier.OVERRIDE)
253+
.addStatement("return %T", concept.conceptObjectType())
254+
.build())
244255
}.build())
245256
}.build()
246257
}
247258

248-
private fun generateConceptWrapperImpl(concept: LanguageSet.ConceptInLanguage): TypeSpec {
249-
return TypeSpec.classBuilder(concept.conceptWrapperImplType()).apply {
250-
addModifiers(KModifier.OPEN)
251-
if (concept.extends().isEmpty()) {
252-
} else {
253-
superclass(concept.extends().first().conceptWrapperImplType())
254-
for (extended in concept.extends().drop(1)) {
255-
addSuperinterface(extended.conceptWrapperInterfaceType(), CodeBlock.of("%T", extended.conceptWrapperInterfaceType()))
256-
}
257-
}
258-
addSuperinterface(concept.conceptWrapperInterfaceType())
259-
260-
primaryConstructor(FunSpec.constructorBuilder().addModifiers(KModifier.PROTECTED).build())
261-
262-
addFunction(FunSpec.builder(ITypedConcept::untyped.name)
263-
.returns(IConcept::class)
264-
.addModifiers(KModifier.OVERRIDE)
265-
.addStatement("return %T", concept.conceptObjectType())
266-
.build())
267-
268-
for (feature in concept.directFeaturesAndConflicts()) {
269-
when (val data = feature.data) {
270-
is PropertyData -> {
271-
addProperty(PropertySpec.builder(feature.validName, GeneratedProperty::class.asClassName().parameterizedBy(data.asKotlinType()))
272-
.addModifiers(KModifier.OVERRIDE)
273-
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
274-
.build())
275-
}
276-
is ChildLinkData -> {
277-
addProperty(PropertySpec.builder(feature.validName, feature.generatedChildLinkType())
278-
.addModifiers(KModifier.OVERRIDE)
279-
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
280-
.build())
281-
}
282-
is ReferenceLinkData -> {
283-
addProperty(PropertySpec.builder(feature.validName, feature.generatedReferenceLinkType())
284-
.addModifiers(KModifier.OVERRIDE)
285-
.getter(FunSpec.getterBuilder().addCode(feature.returnKotlinRef()).build())
286-
.build())
287-
}
288-
}
289-
}
290-
}.build()
291-
}
292-
293259
private fun generateNodeWrapperImpl(concept: LanguageSet.ConceptInLanguage): TypeSpec {
294260
return TypeSpec.classBuilder(concept.nodeWrapperImplType()).apply {
295261
addModifiers(KModifier.OPEN)
296-
addProperty(PropertySpec.builder(TypedNodeImpl::_concept.name, concept.conceptWrapperImplType(), KModifier.OVERRIDE)
262+
addProperty(PropertySpec.builder(TypedNodeImpl::_concept.name, concept.conceptWrapperInterfaceType(), KModifier.OVERRIDE)
297263
.getter(FunSpec.getterBuilder().addStatement("""return %T""", concept.conceptWrapperInterfaceType()).build())
298264
.build())
299265

@@ -437,7 +403,7 @@ fun PropertyType.asKotlinType(): TypeName {
437403
}
438404
}
439405
fun String.parseClassName() = ClassName(substringBeforeLast("."), substringAfterLast("."))
440-
fun ConceptRef.conceptWrapperImplType() = ClassName(languageName, conceptName.conceptWrapperImplName())
406+
//fun ConceptRef.conceptWrapperImplType() = ClassName(languageName, conceptName.conceptWrapperImplName())
441407
fun ConceptRef.conceptWrapperInterfaceType() = ClassName(languageName, conceptName.conceptWrapperInterfaceName())
442408
fun ConceptRef.nodeWrapperImplType() = ClassName(languageName, conceptName.nodeWrapperImplName())
443409
fun ConceptRef.nodeWrapperInterfaceType() = ClassName(languageName, conceptName.nodeWrapperInterfaceName())
@@ -469,7 +435,7 @@ fun LanguageSet.ConceptInLanguage.conceptObjectType() = ClassName(language.name,
469435
fun LanguageSet.ConceptInLanguage.nodeWrapperImplName() = concept.nodeWrapperImplName()
470436
fun LanguageSet.ConceptInLanguage.nodeWrapperImplType() = ClassName(language.name, concept.nodeWrapperImplName())
471437
fun LanguageSet.ConceptInLanguage.nodeWrapperInterfaceType() = ClassName(language.name, concept.nodeWrapperInterfaceName())
472-
fun LanguageSet.ConceptInLanguage.conceptWrapperImplType() = ClassName(language.name, concept.conceptWrapperImplName())
438+
//fun LanguageSet.ConceptInLanguage.conceptWrapperImplType() = ClassName(language.name, concept.conceptWrapperImplName())
473439
fun LanguageSet.ConceptInLanguage.conceptWrapperInterfaceType() = ClassName(language.name, concept.conceptWrapperInterfaceName())
474440

475441
fun FeatureInConcept.kotlinRef() = CodeBlock.of("%T.%N", concept.conceptObjectType(), validName)

metamodel-runtime/src/commonMain/kotlin/org/modelix/metamodel/GeneratedConcept.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ package org.modelix.metamodel
33
import org.modelix.model.api.*
44
import kotlin.reflect.KClass
55

6-
abstract class GeneratedConcept<InstanceT : ITypedNode, WrapperT : ITypedConcept>(
6+
abstract class GeneratedConcept<NodeT : ITypedNode, ConceptT : ITypedConcept>(
77
private val name: String,
88
private val is_abstract: Boolean
99
) : IConcept {
1010
@Deprecated("use .typed()", ReplaceWith("typed()"))
11-
val _typed: WrapperT get() = typed()
12-
abstract fun typed(): WrapperT
13-
abstract fun getInstanceClass(): KClass<InstanceT>
11+
val _typed: ConceptT get() = typed()
12+
abstract fun typed(): ConceptT
13+
abstract fun getInstanceClass(): KClass<out NodeT>
1414
private val propertiesMap: MutableMap<String, GeneratedProperty<*>> = LinkedHashMap()
1515
private val childLinksMap: MutableMap<String, GeneratedChildLink<*, *>> = LinkedHashMap()
1616
private val referenceLinksMap: MutableMap<String, GeneratedReferenceLink<*, *>> = LinkedHashMap()
1717

18-
abstract fun wrap(node: INode): InstanceT
18+
abstract fun wrap(node: INode): NodeT
1919

2020
override fun isAbstract(): Boolean {
2121
return is_abstract

0 commit comments

Comments
 (0)