Skip to content

Commit e685894

Browse files
committed
feat(mps-model-adapters): add reference resolution and deserialization
1 parent 37555c0 commit e685894

File tree

3 files changed

+289
-16
lines changed

3 files changed

+289
-16
lines changed

mps-model-adapters/src/main/kotlin/org/modelix/model/mpsadapters/MPSArea.kt

Lines changed: 217 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,37 @@
1313
*/
1414
package org.modelix.model.mpsadapters
1515

16+
import jetbrains.mps.project.ProjectBase
17+
import jetbrains.mps.project.ProjectManager
18+
import jetbrains.mps.project.facets.JavaModuleFacet
19+
import jetbrains.mps.project.structure.modules.ModuleReference
1620
import jetbrains.mps.smodel.GlobalModelAccess
21+
import jetbrains.mps.smodel.SNodePointer
1722
import org.jetbrains.mps.openapi.module.SRepository
23+
import org.jetbrains.mps.openapi.persistence.PersistenceFacade
1824
import org.modelix.model.api.IBranch
1925
import org.modelix.model.api.IConcept
2026
import org.modelix.model.api.IConceptReference
2127
import org.modelix.model.api.INode
2228
import org.modelix.model.api.INodeReference
29+
import org.modelix.model.api.NodeReference
2330
import org.modelix.model.area.IArea
2431
import org.modelix.model.area.IAreaListener
2532
import org.modelix.model.area.IAreaReference
2633

2734
data class MPSArea(val repository: SRepository) : IArea, IAreaReference {
35+
36+
private fun resolveMPSModelReference(ref: INodeReference): INode {
37+
if (ref is MPSModelReference) {
38+
return ref.modelReference.resolve(repository).let { MPSModelAsNode(it) }
39+
}
40+
41+
val serialized = ref.serialize().substringAfter("${MPSModelReference.PREFIX}:")
42+
val modelRef = PersistenceFacade.getInstance().createModelReference(serialized)
43+
44+
return MPSModelAsNode(modelRef.resolve(repository))
45+
}
46+
2847
override fun getRoot(): INode {
2948
return MPSRepositoryAsNode(repository)
3049
}
@@ -35,11 +54,22 @@ data class MPSArea(val repository: SRepository) : IArea, IAreaReference {
3554
}
3655

3756
override fun resolveNode(ref: INodeReference): INode? {
38-
when (ref) {
39-
is MPSModuleReference -> return ref.moduleReference.resolve(repository)?.let { MPSModuleAsNode(it) }
57+
val serialized = ref.serialize()
58+
val prefix = serialized.substringBefore(":")
59+
return when (prefix) {
60+
MPSModuleReference.PREFIX -> resolveMPSModuleReference(ref)
61+
MPSModelReference.PREFIX -> resolveMPSModelReference(ref)
62+
MPSNodeReference.PREFIX, "mps-node" -> resolveMPSNodeReference(ref) // mps-node for backwards compatibility
63+
MPSDevKitDependencyReference.PREFIX -> resolveMPSDevKitDependencyReference(ref)
64+
MPSJavaModuleFacetReference.PREFIX -> resolveMPSJavaModuleFacetReference(ref)
65+
MPSModelImportReference.PREFIX -> resolveMPSModelImportReference(ref)
66+
MPSModuleDependencyReference.PREFIX -> resolveMPSModuleDependencyReference(ref)
67+
MPSProjectReference.PREFIX -> resolveMPSProjectReference(ref)
68+
MPSProjectModuleReference.PREFIX -> resolveMPSProjectModuleReference(ref)
69+
MPSSingleLanguageDependencyReference.PREFIX -> resolveMPSSingleLanguageDependencyReference(ref)
70+
MPSRepositoryReference.PREFIX -> resolveMPSRepositoryReference()
71+
else -> null
4072
}
41-
42-
return MPSNodeReference.tryConvert(ref)?.ref?.resolve(repository)?.let { MPSNode(it) }
4373
}
4474

4575
override fun resolveOriginalNode(ref: INodeReference): INode? {
@@ -95,4 +125,187 @@ data class MPSArea(val repository: SRepository) : IArea, IAreaReference {
95125
override fun removeListener(l: IAreaListener) {
96126
throw UnsupportedOperationException("Not implemented")
97127
}
128+
129+
private fun resolveMPSModuleReference(ref: INodeReference): MPSModuleAsNode? {
130+
val moduleRef = if (ref is MPSModuleReference) {
131+
ref.moduleReference
132+
} else {
133+
val serializedRef = ref.serialize().substringAfter("${MPSModuleReference.PREFIX}:")
134+
ModuleReference.parseReference(serializedRef)
135+
}
136+
137+
return moduleRef.resolve(repository)?.let { MPSModuleAsNode(it) }
138+
}
139+
140+
private fun resolveMPSNodeReference(ref: INodeReference): MPSNode? {
141+
val sNodeReference = if (ref is MPSNodeReference) {
142+
ref.ref
143+
} else {
144+
val serialized = ref.serialize()
145+
val serializedMPSRef = when {
146+
serialized.startsWith("mps-node:") -> serialized.substringAfter("mps-node:")
147+
serialized.startsWith("mps:") -> serialized.substringAfter("mps:")
148+
else -> return null
149+
}
150+
SNodePointer.deserialize(serializedMPSRef)
151+
}
152+
153+
return sNodeReference.resolve(repository)?.let { MPSNode(it) }
154+
}
155+
156+
private fun resolveMPSDevKitDependencyReference(ref: INodeReference): MPSDevKitDependencyAsNode? {
157+
if (ref is MPSDevKitDependencyReference) {
158+
return when {
159+
ref.userModule != null -> ref.userModule.resolve(repository)
160+
?.let { MPSModuleAsNode(it).findDevKitDependency(ref.usedModuleId) }
161+
ref.userModel != null -> ref.userModel.resolve(repository)
162+
?.let { MPSModelAsNode(it).findDevKitDependency(ref.usedModuleId) }
163+
else -> throw IllegalStateException("No importer found.")
164+
}
165+
}
166+
val serialized = ref.serialize()
167+
val serializedModuleId = serialized.substringAfter("${MPSDevKitDependencyReference.PREFIX}:")
168+
.substringBefore(MPSDevKitDependencyReference.SEPARATOR)
169+
170+
val importer = serialized.substringAfter(MPSDevKitDependencyReference.SEPARATOR)
171+
val foundImporter = resolveNode(NodeReference(importer))
172+
173+
val moduleId = PersistenceFacade.getInstance().createModuleId(serializedModuleId)
174+
175+
return when (foundImporter) {
176+
is MPSModelAsNode -> foundImporter.findDevKitDependency(moduleId)
177+
is MPSModuleAsNode -> foundImporter.findDevKitDependency(moduleId)
178+
else -> null
179+
}
180+
}
181+
182+
private fun resolveMPSJavaModuleFacetReference(ref: INodeReference): MPSJavaModuleFacetAsNode? {
183+
val moduleRef = if (ref is MPSJavaModuleFacetReference) {
184+
ref.moduleReference
185+
} else {
186+
val serialized = ref.serialize()
187+
val serializedModuleRef = serialized.substringAfter("${MPSJavaModuleFacetReference.PREFIX}:")
188+
ModuleReference.parseReference(serializedModuleRef)
189+
}
190+
191+
val facet = moduleRef.resolve(repository)?.getFacetOfType(JavaModuleFacet.FACET_TYPE)
192+
return facet?.let { MPSJavaModuleFacetAsNode(it as JavaModuleFacet) }
193+
}
194+
195+
private fun resolveMPSModelImportReference(ref: INodeReference): MPSModelImportAsNode? {
196+
val serialized = ref.serialize()
197+
val importedModelRef = if (ref is MPSModelImportReference) {
198+
ref.importedModel
199+
} else {
200+
val serializedModelRef = serialized
201+
.substringAfter("${MPSModelImportReference.PREFIX}:")
202+
.substringBefore(MPSModelImportReference.SEPARATOR)
203+
PersistenceFacade.getInstance().createModelReference(serializedModelRef)
204+
}
205+
206+
val importingModelRef = if (ref is MPSModelImportReference) {
207+
ref.importingModel
208+
} else {
209+
val serializedModelRef = serialized.substringAfter(MPSModelImportReference.SEPARATOR)
210+
PersistenceFacade.getInstance().createModelReference(serializedModelRef)
211+
}
212+
213+
val importedModel = importedModelRef.resolve(repository) ?: return null
214+
val importingModel = importingModelRef.resolve(repository) ?: return null
215+
216+
return MPSModelImportAsNode(importedModel = importedModel, importingModel = importingModel)
217+
}
218+
219+
private fun resolveMPSModuleDependencyReference(ref: INodeReference): MPSModuleDependencyAsNode? {
220+
val serialized = ref.serialize()
221+
val usedModuleId = if (ref is MPSModuleDependencyReference) {
222+
ref.usedModuleId
223+
} else {
224+
val serializedModuleId = serialized
225+
.substringAfter("${MPSModuleDependencyReference.PREFIX}:")
226+
.substringBefore(MPSModuleDependencyReference.SEPARATOR)
227+
PersistenceFacade.getInstance().createModuleId(serializedModuleId)
228+
}
229+
230+
val userModuleReference = if (ref is MPSModuleDependencyReference) {
231+
ref.userModuleReference
232+
} else {
233+
val serializedModuleRef = serialized.substringAfter(MPSModuleDependencyReference.SEPARATOR)
234+
ModuleReference.parseReference(serializedModuleRef)
235+
}
236+
237+
return userModuleReference.resolve(repository)
238+
?.let { MPSModuleAsNode(it) }
239+
?.findModuleDependency(usedModuleId)
240+
}
241+
242+
private fun resolveMPSProjectReference(ref: INodeReference): MPSProjectAsNode? {
243+
val projectName = if (ref is MPSProjectReference) {
244+
ref.projectName
245+
} else {
246+
ref.serialize().substringAfter("${MPSProjectReference.PREFIX}:")
247+
}
248+
249+
val project = ProjectManager.getInstance().openedProjects
250+
.filterIsInstance<ProjectBase>()
251+
.find { it.name == projectName }
252+
253+
return project?.let { MPSProjectAsNode(it) }
254+
}
255+
256+
private fun resolveMPSProjectModuleReference(ref: INodeReference): MPSProjectModuleAsNode? {
257+
val serialized = ref.serialize()
258+
val moduleRef = if (ref is MPSProjectModuleReference) {
259+
ref.moduleRef
260+
} else {
261+
val serializedModuleRef = serialized
262+
.substringAfter("${MPSProjectModuleReference.PREFIX}:")
263+
.substringBefore(MPSProjectModuleReference.SEPARATOR)
264+
ModuleReference.parseReference(serializedModuleRef)
265+
}
266+
267+
val projectRef = if (ref is MPSProjectModuleReference) {
268+
ref.projectRef
269+
} else {
270+
val projectRef = serialized.substringAfter(MPSProjectModuleReference.SEPARATOR)
271+
NodeReference(projectRef)
272+
}
273+
274+
return moduleRef.resolve(repository)?.let {
275+
MPSProjectModuleAsNode(
276+
project = (resolveNode(projectRef) as MPSProjectAsNode).project,
277+
module = it,
278+
)
279+
}
280+
}
281+
282+
private fun resolveMPSSingleLanguageDependencyReference(ref: INodeReference): MPSSingleLanguageDependencyAsNode? {
283+
if (ref is MPSSingleLanguageDependencyReference) {
284+
return when {
285+
ref.userModule != null -> ref.userModule.resolve(repository)
286+
?.let { MPSModuleAsNode(it).findSingleLanguageDependency(ref.usedModuleId) }
287+
ref.userModel != null -> ref.userModel.resolve(repository)
288+
?.let { MPSModelAsNode(it).findSingleLanguageDependency(ref.usedModuleId) }
289+
else -> throw IllegalStateException("No importer found.")
290+
}
291+
}
292+
val serialized = ref.serialize()
293+
val serializedModuleId = serialized.substringAfter("${MPSSingleLanguageDependencyReference.PREFIX}:")
294+
.substringBefore(MPSSingleLanguageDependencyReference.SEPARATOR)
295+
296+
val importer = serialized.substringAfter(MPSSingleLanguageDependencyReference.SEPARATOR)
297+
val foundImporter = resolveNode(NodeReference(importer))
298+
299+
val moduleId = PersistenceFacade.getInstance().createModuleId(serializedModuleId)
300+
301+
return when (foundImporter) {
302+
is MPSModelAsNode -> foundImporter.findSingleLanguageDependency(moduleId)
303+
is MPSModuleAsNode -> foundImporter.findSingleLanguageDependency(moduleId)
304+
else -> null
305+
}
306+
}
307+
308+
private fun resolveMPSRepositoryReference(): MPSRepositoryAsNode {
309+
return MPSRepositoryAsNode(repository)
310+
}
98311
}

0 commit comments

Comments
 (0)