Skip to content

Commit 024cac7

Browse files
committed
concept interfaces now have a type parameter for the node type
This allows to use type concepts directly instead of the class GeneratedConcept which was the only one that combined these two types. The drawback is that you now have to always write e.g. C_Entity<N_Entity>, but there is a type alias CN_Entity for that.
1 parent d9a7847 commit 024cac7

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class MetaModelGenerator(val outputDir: Path) {
8181
builder.superclass(GeneratedLanguage::class)
8282
builder.addSuperclassConstructorParameter("\"${language.name}\"")
8383
for (concept in language.getConceptsInLanguage()) {
84-
builder.addProperty(PropertySpec.builder(concept.simpleName, concept.conceptObjectType())
85-
.initializer("%T", concept.conceptObjectType())
84+
builder.addProperty(PropertySpec.builder(concept.simpleName, concept.conceptWrapperInterfaceType())
85+
.initializer("%T", concept.conceptWrapperInterfaceClass())
8686
.build())
8787
}
8888
return builder.build()
@@ -92,6 +92,7 @@ class MetaModelGenerator(val outputDir: Path) {
9292
FileSpec.builder(concept.language.name, concept.concept.name)
9393
.addFileComment(headerComment)
9494
.addType(generateConceptObject(concept))
95+
.addTypeAlias(TypeAliasSpec.builder("CN_" + concept.simpleName, concept.conceptWrapperInterfaceType()).build())
9596
.addType(generateConceptWrapperInterface(concept))
9697
// .addType(generateConceptWrapperImpl(concept))
9798
.addType(generateNodeWrapperInterface(concept))
@@ -151,7 +152,7 @@ class MetaModelGenerator(val outputDir: Path) {
151152
.build())
152153
addFunction(FunSpec.builder(GeneratedConcept<*, *>::typed.name)
153154
.addModifiers(KModifier.OVERRIDE)
154-
.addStatement("""return %T""", concept.conceptWrapperInterfaceType())
155+
.addStatement("""return %T""", concept.conceptWrapperInterfaceClass())
155156
.build())
156157
addProperty(PropertySpec.builder(IConcept::language.name, ILanguage::class, KModifier.OVERRIDE)
157158
.initializer(concept.language.generatedClassName().simpleName)
@@ -219,10 +220,12 @@ class MetaModelGenerator(val outputDir: Path) {
219220
}
220221

221222
private fun generateConceptWrapperInterface(concept: LanguageSet.ConceptInLanguage): TypeSpec {
222-
return TypeSpec.interfaceBuilder(concept.conceptWrapperInterfaceType()).apply {
223-
addSuperinterface(ITypedConcept::class)
223+
return TypeSpec.interfaceBuilder(concept.conceptWrapperInterfaceClass()).apply {
224+
val nodeT = TypeVariableName("NodeT", ITypedNode::class, variance = KModifier.OUT)
225+
addTypeVariable(nodeT)
226+
addSuperinterface(IConceptOfTypedNode::class.asTypeName().parameterizedBy(nodeT))
224227
for (extended in concept.extended()) {
225-
addSuperinterface(extended.conceptWrapperInterfaceType())
228+
addSuperinterface(extended.conceptWrapperInterfaceClass().parameterizedBy(nodeT))
226229
}
227230
for (feature in concept.directFeatures()) {
228231
when (val data = feature.data) {
@@ -260,7 +263,7 @@ class MetaModelGenerator(val outputDir: Path) {
260263
return TypeSpec.classBuilder(concept.nodeWrapperImplType()).apply {
261264
addModifiers(KModifier.OPEN)
262265
addProperty(PropertySpec.builder(TypedNodeImpl::_concept.name, concept.conceptWrapperInterfaceType(), KModifier.OVERRIDE)
263-
.getter(FunSpec.getterBuilder().addStatement("""return %T""", concept.conceptWrapperInterfaceType()).build())
266+
.getter(FunSpec.getterBuilder().addStatement("""return %T""", concept.conceptWrapperInterfaceClass()).build())
264267
.build())
265268

266269
if (concept.extends().size > 1) {
@@ -404,7 +407,8 @@ fun PropertyType.asKotlinType(): TypeName {
404407
}
405408
fun String.parseClassName() = ClassName(substringBeforeLast("."), substringAfterLast("."))
406409
//fun ConceptRef.conceptWrapperImplType() = ClassName(languageName, conceptName.conceptWrapperImplName())
407-
fun ConceptRef.conceptWrapperInterfaceType() = ClassName(languageName, conceptName.conceptWrapperInterfaceName())
410+
fun ConceptRef.conceptWrapperInterfaceType() = conceptWrapperInterfaceClass().parameterizedBy(nodeWrapperInterfaceType())
411+
fun ConceptRef.conceptWrapperInterfaceClass() = ClassName(languageName, conceptName.conceptWrapperInterfaceName())
408412
fun ConceptRef.nodeWrapperImplType() = ClassName(languageName, conceptName.nodeWrapperImplName())
409413
fun ConceptRef.nodeWrapperInterfaceType() = ClassName(languageName, conceptName.nodeWrapperInterfaceName())
410414

@@ -436,7 +440,8 @@ fun LanguageSet.ConceptInLanguage.nodeWrapperImplName() = concept.nodeWrapperImp
436440
fun LanguageSet.ConceptInLanguage.nodeWrapperImplType() = ClassName(language.name, concept.nodeWrapperImplName())
437441
fun LanguageSet.ConceptInLanguage.nodeWrapperInterfaceType() = ClassName(language.name, concept.nodeWrapperInterfaceName())
438442
//fun LanguageSet.ConceptInLanguage.conceptWrapperImplType() = ClassName(language.name, concept.conceptWrapperImplName())
439-
fun LanguageSet.ConceptInLanguage.conceptWrapperInterfaceType() = ClassName(language.name, concept.conceptWrapperInterfaceName())
443+
fun LanguageSet.ConceptInLanguage.conceptWrapperInterfaceType() = ref().conceptWrapperInterfaceType()
444+
fun LanguageSet.ConceptInLanguage.conceptWrapperInterfaceClass() = ref().conceptWrapperInterfaceClass()
440445

441446
fun FeatureInConcept.kotlinRef() = CodeBlock.of("%T.%N", concept.conceptObjectType(), validName)
442447
fun FeatureInConcept.returnKotlinRef() = CodeBlock.of("return %T.%N", concept.conceptObjectType(), validName)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fun IConcept.typed(): ITypedConcept = when (this) {
1919
else -> FallbackTypedConcept(this)
2020
}
2121

22-
interface IConceptOfTypedNode<NodeT : ITypedNode> : ITypedConcept {
22+
interface IConceptOfTypedNode<out NodeT : ITypedNode> : ITypedConcept {
2323
fun getInstanceInterface(): KClass<out NodeT>
2424
}
2525

@@ -28,7 +28,7 @@ fun <NodeT : ITypedNode> IConceptOfTypedNode<NodeT>.getInstanceClass(): KClass<o
2828
return getInstanceInterface()
2929
}
3030

31-
interface INonAbstractConcept<NodeT : ITypedNode> : IConceptOfTypedNode<NodeT>
31+
interface INonAbstractConcept<out NodeT : ITypedNode> : IConceptOfTypedNode<NodeT>
3232

3333
interface ITypedConceptFeature
3434

0 commit comments

Comments
 (0)