Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MODELIX-605 Implement adapters for the direction I -> S #318

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,31 @@

package org.modelix.model.mpsadapters.mps

import jetbrains.mps.lang.smodel.generator.smodelAdapter.SConceptOperations
import jetbrains.mps.smodel.MPSModuleRepository
import org.jetbrains.mps.openapi.language.SConcept
import org.jetbrains.mps.openapi.model.SModel
import org.jetbrains.mps.openapi.model.SModel.Problem
import org.jetbrains.mps.openapi.model.SModelId
import org.jetbrains.mps.openapi.model.SModelListener
import org.jetbrains.mps.openapi.model.SModelName
import org.jetbrains.mps.openapi.model.SModelReference
import org.jetbrains.mps.openapi.model.SNode
import org.jetbrains.mps.openapi.model.SNodeAccessListener
import org.jetbrains.mps.openapi.model.SNodeChangeListener
import org.jetbrains.mps.openapi.model.SNodeId
import org.jetbrains.mps.openapi.module.SRepository
import org.jetbrains.mps.openapi.persistence.DataSource
import org.jetbrains.mps.openapi.persistence.PersistenceFacade
import org.modelix.model.api.BuiltinLanguages
import org.modelix.model.api.INode
import org.modelix.model.api.getDescendants
import org.modelix.model.api.remove
import org.modelix.model.mpsadapters.MPSConcept
import org.modelix.model.mpsadapters.MPSModelReference
import org.modelix.model.mpsadapters.Model

class NodeAsMPSModel private constructor(private val node: INode, private val sRepository: SRepository?) : SModel {
data class NodeAsMPSModel(val node: INode, val sRepository: SRepository?) : SModel {

Check warning

Code scanning / detekt

Too many functions inside a/an file/class/object/interface always indicate a violation of the single responsibility principle. Maybe the file/class/object/interface wants to manage too many things at once. Extract functionality which clearly belongs together. Warning

Class 'NodeAsMPSModel' with '25' functions detected. Defined threshold inside classes is set to '11'
companion object {
fun wrap(modelNode: INode, repository: SRepository?): SModel = NodeAsMPSModel(modelNode, repository)
}
Expand All @@ -45,16 +55,29 @@

override fun addModelListener(l: SModelListener?) = throw UnsupportedOperationException("Not implemented")

override fun addRootNode(node: SNode?) = throw UnsupportedOperationException("Not implemented")
override fun addRootNode(node: SNode?) {
if (node != null) {
this.node.addNewChild(BuiltinLanguages.MPSRepositoryConcepts.Model.rootNodes, -1, MPSConcept(node.concept))
}
}

override fun createNode(concept: SConcept) = throw UnsupportedOperationException("Not implemented")
override fun createNode(concept: SConcept): SNode? {
return SConceptOperations.createNewNode(concept)
}

override fun createNode(concept: SConcept, nodeId: SNodeId?) =
throw UnsupportedOperationException("Not implemented")
override fun createNode(concept: SConcept, nodeId: SNodeId?): SNode? {
// TODO can we set the id somehow?
return SConceptOperations.createNewNode(concept)
}

override fun getModelId() = throw UnsupportedOperationException("Not implemented")
override fun getModelId(): SModelId {
val serialized = checkNotNull(node.getPropertyValue(BuiltinLanguages.MPSRepositoryConcepts.Model.id)) {
"No model id found"
}
return PersistenceFacade.getInstance().createModelId(serialized)
}

@Deprecated("Deprecated in Java")
@Deprecated("Deprecated in Java", ReplaceWith("getName()"))
override fun getModelName() = name.value

override fun getModelRoot() = throw UnsupportedOperationException("Not implemented")
Expand All @@ -72,38 +95,46 @@
adapter
}

override fun getSource() = throw UnsupportedOperationException("Not implemented")
override fun getSource() = object : DataSource {
override fun getLocation() = "modelix"
override fun getTimestamp() = 0L
override fun isReadOnly() = true
}

override fun isLoaded() = true

override fun isReadOnly() = true

override fun load() = throw UnsupportedOperationException("Not implemented")
override fun load() { /* no-op */ }

override fun removeAccessListener(l: SNodeAccessListener?) = throw UnsupportedOperationException("Not implemented")

override fun removeChangeListener(l: SNodeChangeListener?) = throw UnsupportedOperationException("Not implemented")

override fun removeModelListener(l: SModelListener?) = throw UnsupportedOperationException("Not implemented")

override fun removeRootNode(node: SNode?) = throw UnsupportedOperationException("Not implemented")
override fun removeRootNode(node: SNode?) {
if (node == null) return

override fun unload() = throw UnsupportedOperationException("Not implemented")
val rootNodes = this.node.getChildren(BuiltinLanguages.MPSRepositoryConcepts.Model.rootNodes)
val toDelete = rootNodes.find { it.reference.serialize().endsWith(node.reference.toString()) }
toDelete?.remove()
}

override fun getReference() = throw UnsupportedOperationException("Not implemented")
override fun unload() { /* no-op */ }

override fun getNode(id: SNodeId?) = throw UnsupportedOperationException("Not implemented")
override fun getReference(): SModelReference {
val serialized = node.reference.serialize().substringAfter(MPSModelReference.PREFIX)
return PersistenceFacade.getInstance().createModelReference(serialized)
}

override fun getProblems() = throw UnsupportedOperationException("Not implemented")
override fun getNode(id: SNodeId?): SNode? {
if (id == null) return null

override fun equals(other: Any?) =
if (this === other) {
true
} else if (other == null || other !is NodeAsMPSModel) {
false
} else {
node != other.node
}
val nodeId = PersistenceFacade.getInstance().asString(id)
val node = node.getDescendants(true).firstOrNull { it.reference.serialize().endsWith(nodeId) }
return node?.let { NodeAsMPSNode(it, repository) }
}

override fun hashCode() = 31 + node.hashCode()
override fun getProblems() = emptyList<Problem>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,25 @@

import jetbrains.mps.smodel.MPSModuleRepository
import org.jetbrains.mps.openapi.language.SLanguage
import org.jetbrains.mps.openapi.model.SModel
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.api.getDescendants
import org.modelix.model.mpsadapters.MPSJavaModuleFacetAsNode
import org.modelix.model.mpsadapters.MPSModuleDependencyAsNode
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 {

Check warning

Code scanning / detekt

Too many functions inside a/an file/class/object/interface always indicate a violation of the single responsibility principle. Maybe the file/class/object/interface wants to manage too many things at once. Extract functionality which clearly belongs together. Warning

Class 'NodeAsMPSModule' with '15' functions detected. Defined threshold inside classes is set to '11'

companion object {
fun wrap(modelNode: INode, repository: SRepository?): SModule = NodeAsMPSModule(modelNode, repository)
Expand All @@ -38,21 +48,44 @@

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.mapNotNull { depNode ->
(depNode as? MPSModuleDependencyAsNode)?.let { NodeAsMPSModuleDependency(it, 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")
override fun getModel(id: SModelId?): SModel? {
if (id == null) return null
val modelId = PersistenceFacade.getInstance().asString(id)
val model = node.getDescendants(false).firstOrNull {
it.reference.serialize().endsWith(modelId)
}
return model?.let { NodeAsMPSModel(it, repository) }
}

override fun getModelRoots() = throw UnsupportedOperationException("Not implemented")

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 for $node"
}
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()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.SRepository
import org.modelix.model.mpsadapters.MPSModuleDependencyAsNode
import org.modelix.model.mpsadapters.MPSModuleReference

data class NodeAsMPSModuleDependency(val node: MPSModuleDependencyAsNode, val sRepository: SRepository?) : SDependency {

override fun getScope(): SDependencyScope = checkNotNull(node.dependencyScope) { "Invalid dependency scope for dependency $node" }
override fun isReexport() = node.reexport
override fun getTargetModule() = node.moduleReference

override fun getTarget(): SModule? {
val ref = MPSModuleReference(node.moduleReference)
return node.getArea().resolveNode(ref)?.let { NodeAsMPSModule(it, sRepository) }
}
}
Loading