Skip to content

Commit

Permalink
Merge pull request #238 from Strumenta/emfinternalclasses
Browse files Browse the repository at this point in the history
Supporting the recognition of internal classes when mapping to EMF
  • Loading branch information
ftomassetti authored Jul 4, 2023
2 parents 0582c6d + acfd7e8 commit 8e06607
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
2 changes: 1 addition & 1 deletion emf/src/main/kotlin/com/strumenta/kolasu/emf/Metamodel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ val KClass<*>.eClassifierName: String

val Class<*>.eClassifierName: String
get() = if (this.enclosingClass != null) {
"${this.enclosingClass.simpleName}${this.simpleName}"
"${this.enclosingClass.simpleName}.${this.simpleName}"
} else {
this.simpleName
}
Expand Down
23 changes: 20 additions & 3 deletions emf/src/main/kotlin/com/strumenta/kolasu/emf/MetamodelBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.strumenta.kolasu.emf

import com.strumenta.kolasu.model.PropertyTypeDescription
import com.strumenta.kolasu.model.isANode
import com.strumenta.kolasu.model.processProperties
import org.eclipse.emf.ecore.*
import org.eclipse.emf.ecore.resource.Resource
Expand All @@ -13,12 +14,23 @@ import kotlin.reflect.full.withNullability

private val KClass<*>.packageName: String?
get() {
val qname = this.qualifiedName ?: throw IllegalStateException("The class has no qualified name: $this")
val isInternal = this.java.name.contains('$')
val qname = if (isInternal) {
this.java.name.split("$").first()
} else {
this.qualifiedName ?: throw IllegalStateException("The class has no qualified name: $this")
}
return if (qname == this.simpleName) {
null
} else {
require(qname.endsWith(".${this.simpleName}"))
qname.removeSuffix(".${this.simpleName}")
if (isInternal) {
val last = qname.split(".").last()
require(qname.endsWith(".$last"))
qname.removeSuffix(".$last")
} else {
require(qname.endsWith(".${this.simpleName}"))
qname.removeSuffix(".${this.simpleName}")
}
}
}

Expand Down Expand Up @@ -347,6 +359,11 @@ class MetamodelBuilder(packageName: String, nsURI: String, nsPrefix: String, res
queue.add(it)
}
}
kClass.nestedClasses.forEach {
if (it.isANode()) {
queue.add(it)
}
}
}
while (queue.isNotEmpty()) {
provideClass(queue.removeFirst())
Expand Down
23 changes: 22 additions & 1 deletion emf/src/test/kotlin/com/strumenta/kolasu/emf/MetamodelTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ class MetamodelTest {
)
metamodelBuilder.provideClass(NodeWithReference::class)
val ePackage = metamodelBuilder.generate()
println(ePackage.saveAsJsonObject().toString())
assertEquals("com.strumenta.kolasu.emf", ePackage.name)
assertEquals(1, ePackage.eClassifiers.size)

Expand All @@ -162,4 +161,26 @@ class MetamodelTest {
val pointers = nodeWithReference.eStructuralFeatures.find { it.name == "pointers" } as EReference
assertEquals(true, pointers.isContainment)
}

@Test
fun internalClasses() {
val metamodelBuilder = MetamodelBuilder(
"com.strumenta.kolasu.emf",
"https://strumenta.com/simplemm", "simplemm"
)
metamodelBuilder.provideClass(MyClassWithInternalClasses::class)
val ePackage = metamodelBuilder.generate()
assertEquals("com.strumenta.kolasu.emf", ePackage.name)
assertEquals(2, ePackage.eClassifiers.size)
val MyClassWithInternalClasses = ePackage.eClassifiers[0]
val Internal = ePackage.eClassifiers[1]
assertEquals("MyClassWithInternalClasses", MyClassWithInternalClasses.name)
assertEquals("MyClassWithInternalClasses.Internal", Internal.name)
}
}

class MyClassWithInternalClasses : Node() {
class Internal : Node()

class InternalWhichIsNotANode
}

0 comments on commit 8e06607

Please sign in to comment.