diff --git a/model-api/src/commonMain/kotlin/org/modelix/model/api/IConcept.kt b/model-api/src/commonMain/kotlin/org/modelix/model/api/IConcept.kt index 2c3ff5d017..da3d0f109f 100644 --- a/model-api/src/commonMain/kotlin/org/modelix/model/api/IConcept.kt +++ b/model-api/src/commonMain/kotlin/org/modelix/model/api/IConcept.kt @@ -181,3 +181,22 @@ interface IConcept { fun IConcept?.isSubConceptOf(superConcept: IConcept?) = this?.isSubConceptOf(superConcept) == true fun IConcept.conceptAlias() = getConceptProperty("alias") + +/** + * Checks if this is a sub-concept of the [IConcept] that is identified by the [superConceptReference]'s UID. + * + * @param superConceptReference a reference to the potential super-concept + * @return true if this concept (or any of its ancestors) has the same UID as the [superConceptReference] + */ +fun IConcept.isSubConceptOf(superConceptReference: IConceptReference): Boolean { + if (this.getUID() == superConceptReference.getUID()) { + return true + } else { + for (parent in getDirectSuperConcepts()) { + if (parent.isSubConceptOf(superConceptReference)) { + return true + } + } + } + return false +} diff --git a/model-api/src/commonTest/kotlin/org/modelix/model/api/IConceptTests.kt b/model-api/src/commonTest/kotlin/org/modelix/model/api/IConceptTests.kt new file mode 100644 index 0000000000..6b464418b1 --- /dev/null +++ b/model-api/src/commonTest/kotlin/org/modelix/model/api/IConceptTests.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024. + * + * 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.api + +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class IConceptTests { + + @Test + fun isModuleSubConceptOfModuleBasedOnUid() { + val moduleConcept = BuiltinLanguages.MPSRepositoryConcepts.Module + val isSubConcept = moduleConcept.isSubConceptOf(BuiltinLanguages.MPSRepositoryConcepts.Module.getReference()) + assertTrue(isSubConcept) + } + + @Test + fun isModelNotSubConceptOfModuleBasedOnUid() { + val modelConcept = BuiltinLanguages.MPSRepositoryConcepts.Model + val moduleConcept = BuiltinLanguages.MPSRepositoryConcepts.Module.getReference() + val isNotSubConcept = modelConcept.isSubConceptOf(moduleConcept) + assertFalse(isNotSubConcept) + } + + @Test + fun isModuleSubConceptOfNamedConceptBasedOnUid() { + val moduleConcept = BuiltinLanguages.MPSRepositoryConcepts.Module + val namedConcept = BuiltinLanguages.jetbrains_mps_lang_core.INamedConcept.getReference() + val isSubConcept = moduleConcept.isSubConceptOf(namedConcept) + assertTrue(isSubConcept) + } +}