Skip to content

Commit cb6d8d6

Browse files
committed
feat(metamodel-export): serialize annotations on concept nodes into the metamodel json
1 parent 83f3a06 commit cb6d8d6

File tree

3 files changed

+70
-14
lines changed

3 files changed

+70
-14
lines changed

metamodel-export/src/main/kotlin/org/modelix/metamodel/export/MPSMetaModelExporter.kt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import org.jetbrains.mps.openapi.language.SInterfaceConcept
2020
import org.jetbrains.mps.openapi.language.SProperty
2121
import org.jetbrains.mps.openapi.language.SReferenceLink
2222
import org.jetbrains.mps.openapi.model.SNode
23+
import org.modelix.metamodel.export.MPSModelExporter.Companion.exportNode
24+
import org.modelix.model.data.AnnotationData
2325
import org.modelix.model.data.ChildLinkData
2426
import org.modelix.model.data.ConceptData
2527
import org.modelix.model.data.EnumData
@@ -113,6 +115,9 @@ class MPSMetaModelExporter(private val outputFolder: File) {
113115
}
114116
fqName(it)
115117
}
118+
val smodelAttributes = SNodeOperations
119+
.getChildren(concept, LINKS.smodelAttribute)
120+
.map(::exportAnnotation)
116121
val metaProperties: MutableMap<String, String> = HashMap()
117122
if (SPropertyOperations.getString(concept, PROPS.conceptAlias) != null) {
118123
metaProperties[ConceptData.ALIAS_KEY] =
@@ -127,6 +132,7 @@ class MPSMetaModelExporter(private val outputFolder: File) {
127132
referenceLinks,
128133
superConcepts,
129134
deprecationMsg(concept),
135+
smodelAttributes,
130136
metaProperties,
131137
)
132138
}
@@ -172,6 +178,18 @@ class MPSMetaModelExporter(private val outputFolder: File) {
172178
jsonFile.writeText(languageData.toJson(), StandardCharsets.UTF_8)
173179
}
174180

181+
fun exportAnnotation(node: SNode): AnnotationData =
182+
exportNode(node).let {
183+
val annotationConcept = SNodeOperations.getConcept(node)
184+
AnnotationData(
185+
uid = MetaIdByDeclaration.getLinkId(node).toString(),
186+
type = fqName(annotationConcept),
187+
children = it.children,
188+
properties = it.properties,
189+
references = it.references,
190+
)
191+
}
192+
175193
val output: List<LanguageData>
176194
get() = producedData.values.toList()
177195

@@ -195,6 +213,10 @@ class MPSMetaModelExporter(private val outputFolder: File) {
195213
return fqName(target)
196214
}
197215

216+
private fun fqName(concept: SConcept?): String {
217+
return concept?.let { concept.language.sourceModule?.moduleName + "." + concept.name } ?: "unknown"
218+
}
219+
198220
private fun fqName(element: SNode?): String {
199221
return SNodeOperations.getModel(element).module.moduleName + "." + SPropertyOperations.getString(element, PROPS.name)
200222
}
@@ -230,6 +252,13 @@ class MPSMetaModelExporter(private val outputFolder: File) {
230252
"jetbrains.mps.lang.structure.structure.InterfaceConceptDeclaration",
231253
)
232254

255+
val AttributeInfoConceptDeclaration: SConcept = MetaAdapterFactory.getConcept(
256+
-4094437568663370681,
257+
-8968368868337559369,
258+
2992811758677295509,
259+
"jetbrains.mps.lang.structure.structure.AttributeInfo",
260+
)
261+
233262
val INamedConcept: SInterfaceConcept = MetaAdapterFactory.getInterfaceConcept(
234263
-0x3154ae6ada15b0deL,
235264
-0x646defc46a3573f4L,
@@ -295,6 +324,13 @@ class MPSMetaModelExporter(private val outputFolder: File) {
295324
0xeeb344f63fe016cL,
296325
"defaultMember",
297326
)
327+
val smodelAttribute: SContainmentLink = MetaAdapterFactory.getContainmentLink(
328+
-0x3154ae6ada15b0deL,
329+
-0x646defc46a3573f4L,
330+
0x10802efe25aL,
331+
0x47bf8397520e5942L,
332+
"smodelAttribute",
333+
)
298334
}
299335

300336
private object PROPS {
@@ -346,5 +382,12 @@ class MPSMetaModelExporter(private val outputFolder: File) {
346382
0x13b8f6fdce540e38L,
347383
"memberId",
348384
)
385+
val attributeInfoRole: SProperty = MetaAdapterFactory.getProperty(
386+
-4094437568663370681,
387+
-8968368868337559369,
388+
2992811758677295509,
389+
7588428831955550663,
390+
"role",
391+
)
349392
}
350393
}

metamodel-export/src/main/kotlin/org/modelix/metamodel/export/MPSModelExporter.kt

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,23 @@ class MPSModelExporter(private val outputFolder: File) {
9595
return data
9696
}
9797

98-
private fun exportNode(node: SNode): NodeData {
99-
val id: String = node.reference.toString()
100-
val concept: String = "mps:" + MetaIdHelper.getConcept(SNodeOperations.getConcept(node)).serialize()
101-
val role = node.containmentLink?.name ?: "rootNodes"
102-
val children: List<NodeData> = SNodeOperations.getChildren(node).map { exportNode(it) }
103-
val properties: MutableMap<String, String> = LinkedHashMap()
104-
val references: MutableMap<String, String> = LinkedHashMap()
105-
properties["#mpsNodeId#"] = node.nodeId.toString()
106-
for (property: SProperty in node.properties) {
107-
properties[property.name] = node.getProperty(property) ?: continue
108-
}
109-
for (reference: SReference in node.references) {
110-
references[reference.link.name] = reference.targetNodeReference.toString()
98+
companion object {
99+
fun exportNode(node: SNode): NodeData {
100+
val id: String = node.reference.toString()
101+
val concept: String = "mps:" + MetaIdHelper.getConcept(SNodeOperations.getConcept(node)).serialize()
102+
val role = node.containmentLink?.name ?: "rootNodes"
103+
val children: List<NodeData> = SNodeOperations.getChildren(node).map { exportNode(it) }
104+
val properties: MutableMap<String, String> = LinkedHashMap()
105+
val references: MutableMap<String, String> = LinkedHashMap()
106+
properties["#mpsNodeId#"] = node.nodeId.toString()
107+
for (property: SProperty in node.properties) {
108+
properties[property.name] = node.getProperty(property) ?: continue
109+
}
110+
for (reference: SReference in node.references) {
111+
references[reference.link.name] = reference.targetNodeReference.toString()
112+
}
113+
return NodeData(id, concept, role, children, properties, references)
111114
}
112-
return NodeData(id, concept, role, children, properties, references)
113115
}
114116

115117
private object CONCEPTS {

model-api/src/commonMain/kotlin/org/modelix/model/data/MetaModelData.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ data class ConceptData(
4343
val references: List<ReferenceLinkData> = emptyList(),
4444
val extends: List<String> = emptyList(),
4545
override val deprecationMessage: String? = null,
46+
val smodelAttributes: List<AnnotationData> = emptyList(),
4647
val metaProperties: MutableMap<String, String> = mutableMapOf(),
4748
) : IDeprecatable {
4849
companion object {
@@ -133,3 +134,13 @@ data class ReferenceLinkData(
133134
val optional: Boolean = true,
134135
override val deprecationMessage: String? = null,
135136
) : IConceptFeatureData, IDeprecatable
137+
138+
@Serializable
139+
data class AnnotationData(
140+
val uid: String? = null,
141+
val type: String,
142+
val role: String? = null,
143+
val children: List<NodeData> = emptyList(),
144+
val properties: Map<String, String> = emptyMap(),
145+
val references: Map<String, String> = emptyMap(),
146+
)

0 commit comments

Comments
 (0)