From e388d285dab18b6231dbb34f5afef6da020c2d5e Mon Sep 17 00:00:00 2001
From: Michael Huster <mhuster@itemis.com>
Date: Fri, 10 Nov 2023 12:07:03 +0100
Subject: [PATCH] feat(mps-model-adapters): implement stubs in NodeAsMPSModule

---
 .../mpsadapters/mps/NodeAsMPSDependency.kt    | 54 +++++++++++++++++++
 .../model/mpsadapters/mps/NodeAsMPSModule.kt  | 31 +++++++++--
 2 files changed, 80 insertions(+), 5 deletions(-)
 create mode 100644 mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSDependency.kt

diff --git a/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSDependency.kt b/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSDependency.kt
new file mode 100644
index 0000000000..3ea166d99e
--- /dev/null
+++ b/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSDependency.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2023.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.modelix.model.mpsadapters.mps
+
+import org.jetbrains.mps.openapi.module.SDependency
+import org.jetbrains.mps.openapi.module.SDependencyScope
+import org.jetbrains.mps.openapi.module.SModule
+import org.jetbrains.mps.openapi.module.SModuleReference
+import org.jetbrains.mps.openapi.module.SRepository
+import org.modelix.model.api.INode
+import org.modelix.model.mpsadapters.MPSModuleDependencyAsNode
+import org.modelix.model.mpsadapters.MPSModuleReference
+
+data class NodeAsMPSDependency(val node: INode, val sRepository: SRepository?) : SDependency {
+    override fun getScope(): SDependencyScope {
+        return when (node) {
+            is MPSModuleDependencyAsNode -> node.dependencyScope
+            else -> null
+        } ?: error("Node is not a valid dependency")
+    }
+
+    override fun isReexport(): Boolean {
+        return when (node) {
+            is MPSModuleDependencyAsNode -> node.reexport
+            else -> error("Node is not a valid dependency")
+        }
+    }
+
+    override fun getTargetModule(): SModuleReference {
+        return when (node) {
+            is MPSModuleDependencyAsNode -> node.moduleReference
+            else -> null
+        } ?: error("Node is not a valid dependency")
+    }
+
+    override fun getTarget(): SModule? {
+        val ref = MPSModuleReference(targetModule)
+        return node.getArea().resolveNode(ref)?.let { NodeAsMPSModule(it, sRepository) }
+    }
+}
diff --git a/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSModule.kt b/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSModule.kt
index e0722eb99f..734e749fbb 100644
--- a/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSModule.kt
+++ b/mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/mps/NodeAsMPSModule.kt
@@ -19,14 +19,21 @@ package org.modelix.model.mpsadapters.mps
 import jetbrains.mps.smodel.MPSModuleRepository
 import org.jetbrains.mps.openapi.language.SLanguage
 import org.jetbrains.mps.openapi.model.SModelId
+import org.jetbrains.mps.openapi.module.SDependency
 import org.jetbrains.mps.openapi.module.SModule
+import org.jetbrains.mps.openapi.module.SModuleFacet
+import org.jetbrains.mps.openapi.module.SModuleId
 import org.jetbrains.mps.openapi.module.SModuleListener
+import org.jetbrains.mps.openapi.module.SModuleReference
 import org.jetbrains.mps.openapi.module.SRepository
+import org.jetbrains.mps.openapi.persistence.PersistenceFacade
 import org.modelix.model.api.BuiltinLanguages
 import org.modelix.model.api.INode
+import org.modelix.model.mpsadapters.MPSJavaModuleFacetAsNode
+import org.modelix.model.mpsadapters.MPSModuleReference
 import org.modelix.model.mpsadapters.Module
 
-class NodeAsMPSModule private constructor(val node: INode, val sRepository: SRepository?) : SModule {
+data class NodeAsMPSModule(val node: INode, val sRepository: SRepository?) : SModule {
 
     companion object {
         fun wrap(modelNode: INode, repository: SRepository?): SModule = NodeAsMPSModule(modelNode, repository)
@@ -38,9 +45,15 @@ class NodeAsMPSModule private constructor(val node: INode, val sRepository: SRep
 
     override fun addModuleListener(listener: SModuleListener?) = throw UnsupportedOperationException("Not implemented")
 
-    override fun getDeclaredDependencies() = throw UnsupportedOperationException("Not implemented")
+    override fun getDeclaredDependencies(): MutableIterable<SDependency> {
+        val dependencies = node.getChildren(BuiltinLanguages.MPSRepositoryConcepts.Module.dependencies)
+        return dependencies.map { NodeAsMPSDependency(node, sRepository) }.toMutableList()
+    }
 
-    override fun getFacets() = throw UnsupportedOperationException("Not implemented")
+    override fun getFacets(): MutableIterable<SModuleFacet> {
+        val facets = node.getChildren(BuiltinLanguages.MPSRepositoryConcepts.Module.facets)
+        return facets.mapNotNull { (it as? MPSJavaModuleFacetAsNode)?.facet }.toMutableList()
+    }
 
     override fun getModel(id: SModelId?) = throw UnsupportedOperationException("Not implemented")
 
@@ -48,11 +61,19 @@ class NodeAsMPSModule private constructor(val node: INode, val sRepository: SRep
 
     override fun getModels() = node.getChildren(Module.models).map { NodeAsMPSModel.wrap(it, sRepository) }
 
-    override fun getModuleId() = throw UnsupportedOperationException("Not implemented")
+    override fun getModuleId(): SModuleId {
+        val serialized = checkNotNull(node.getPropertyValue(BuiltinLanguages.MPSRepositoryConcepts.Module.id)) {
+            "Module id was null"
+        }
+        return PersistenceFacade.getInstance().createModuleId(serialized)
+    }
 
     override fun getModuleName() = node.getPropertyValue(BuiltinLanguages.jetbrains_mps_lang_core.INamedConcept.name)
 
-    override fun getModuleReference() = throw UnsupportedOperationException("Not implemented")
+    override fun getModuleReference(): SModuleReference {
+        val serialized = node.reference.serialize().substringAfter(MPSModuleReference.PREFIX)
+        return PersistenceFacade.getInstance().createModuleReference(serialized)
+    }
 
     override fun getRepository(): SRepository = sRepository ?: MPSModuleRepository.getInstance()