From 2858fb412db642930c8163d43f7388b8857149bf Mon Sep 17 00:00:00 2001 From: Ed Seidewitz Date: Sat, 28 Mar 2026 23:50:35 -0400 Subject: [PATCH 1/3] ST6RI-925 Created a test of desired filtering of FeatureMemberships. - The featureMemberships of a type should only include inheritedMemberships whose owningType is a direct or indirect supertype. --- .../DerivedPropertyAndOperationTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/DerivedPropertyAndOperationTest.java b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/DerivedPropertyAndOperationTest.java index d0b08fe8b6..196af0836c 100644 --- a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/DerivedPropertyAndOperationTest.java +++ b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/DerivedPropertyAndOperationTest.java @@ -43,11 +43,13 @@ import org.omg.sysml.lang.sysml.EnumerationUsage; import org.omg.sysml.lang.sysml.Expression; import org.omg.sysml.lang.sysml.Feature; +import org.omg.sysml.lang.sysml.FeatureMembership; import org.omg.sysml.lang.sysml.ItemUsage; import org.omg.sysml.lang.sysml.Membership; import org.omg.sysml.lang.sysml.Namespace; import org.omg.sysml.lang.sysml.Relationship; import org.omg.sysml.lang.sysml.TriggerInvocationExpression; +import org.omg.sysml.lang.sysml.Type; import org.omg.sysml.lang.sysml.Usage; import org.omg.sysml.lang.sysml.ViewUsage; @@ -351,4 +353,35 @@ public void testLocale() throws Exception { assertEquals("comment.locale", "en_US", comment.getLocale()); assertEquals("doc.locale", "en_US", doc.getLocale()); } + + public final String featureMembershipTest = + "package Test {\n" + + " part def A {\n" + + " attribute f;\n" + + " }\n" + + " part def B {\n" + + " public import A::*;\n" + + " feature g;\n" + + " }\n" + + " part def C :> B;" + + "}"; + + @Test + public void testFeatureMembership() throws Exception { + SysMLInteractive instance = getSysMLInteractiveInstance(); + SysMLInteractiveResult result = instance.process(featureMembershipTest); + Element root = result.getRootElement(); + List elements = ((Namespace)root).getOwnedMember(); + List ownedMembers = ((Namespace)elements.get(0)).getOwnedMember(); + Definition A = (Definition)ownedMembers.get(0); + Definition B = (Definition)ownedMembers.get(1); + Definition C = (Definition)ownedMembers.get(2); + assertTrue("A", testFeatureOwningTypes(A)); + assertTrue("B", testFeatureOwningTypes(B)); + assertTrue("C", testFeatureOwningTypes(C)); + } + + private boolean testFeatureOwningTypes(Type type) { + return type.getFeatureMembership().stream().map(FeatureMembership::getOwningType).allMatch(t->type.specializes(t)); + } } From fe8b0849c65ee03179233ea3f61007b4933595ef Mon Sep 17 00:00:00 2001 From: Ed Seidewitz Date: Sat, 28 Mar 2026 23:52:26 -0400 Subject: [PATCH 2/3] ST6RI-925 Updated derivation for featureMembership. - Added filter that owningType is a supertype. - There is a slight performance degradation. --- .../Type_featureMembership_SettingDelegate.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java b/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java index fcd37b1166..dc5046a9f0 100644 --- a/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java +++ b/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java @@ -22,6 +22,7 @@ package org.omg.sysml.delegate.setting; +import java.util.List; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; @@ -37,11 +38,16 @@ public Type_featureMembership_SettingDelegate(EStructuralFeature eStructuralFeat @Override protected EList basicGet(InternalEObject owner) { + Type self = (Type)owner; + EList featureMemberships = new NonNotifyingEObjectEList<>(FeatureMembership.class, owner, eStructuralFeature.getFeatureID()); - featureMemberships.addAll(((Type)owner).getOwnedFeatureMembership()); - ((Type)owner).getInheritedMembership().stream(). + featureMemberships.addAll(self.getOwnedFeatureMembership()); + // For improved performance, compute supertypes only once. + List allSupertypes = self.allSupertypes(); + self.getInheritedMembership().stream(). filter(FeatureMembership.class::isInstance). map(FeatureMembership.class::cast). + filter(membership->allSupertypes.contains(membership.getOwningType())). forEachOrdered(featureMemberships::add); return featureMemberships; } From 97a9854d4a7091bf313d15bc0f935cbfd9557c0a Mon Sep 17 00:00:00 2001 From: Ed Seidewitz Date: Sun, 29 Mar 2026 00:53:59 -0400 Subject: [PATCH 3/3] ST6RI-925 Cached Type::featureMemberships to improve performance. --- .../org/omg/sysml/adapter/TypeAdapter.java | 23 ++++++++++++++++++- ...ype_featureMembership_SettingDelegate.java | 19 +++------------ .../src/org/omg/sysml/util/TypeUtil.java | 6 ++++- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/org.omg.sysml/src/org/omg/sysml/adapter/TypeAdapter.java b/org.omg.sysml/src/org/omg/sysml/adapter/TypeAdapter.java index 6672b698b2..ca72f2ddef 100644 --- a/org.omg.sysml/src/org/omg/sysml/adapter/TypeAdapter.java +++ b/org.omg.sysml/src/org/omg/sysml/adapter/TypeAdapter.java @@ -46,6 +46,7 @@ import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Expression; import org.omg.sysml.lang.sysml.Feature; +import org.omg.sysml.lang.sysml.FeatureMembership; import org.omg.sysml.lang.sysml.Specialization; import org.omg.sysml.lang.sysml.Membership; import org.omg.sysml.lang.sysml.ResultExpressionMembership; @@ -202,18 +203,38 @@ protected Collection getFeaturesRedefinedByType() { } return redefinedFeatures; } + + public EList getFeatureMembership() { + if (featureMembership == null) { + Type target = getTarget(); + EList featureMemberships = new NonNotifyingEObjectEList(FeatureMembership.class, (InternalEObject) target, SysMLPackage.TYPE__FEATURE_MEMBERSHIP); + featureMemberships.addAll(target.getOwnedFeatureMembership()); + // For improved performance, compute supertypes only once. + List allSupertypes = target.allSupertypes(); + for (Membership membership: target.getInheritedMembership()) { + if (membership instanceof FeatureMembership && + allSupertypes.contains(membership.getMembershipOwningNamespace())) { + featureMemberships.add((FeatureMembership)membership); + } + } + featureMembership = featureMemberships; + } + return featureMembership; + } // Caching private EList inheritedMembership = null; private EList nonPrivateMembership = null; - private Collection redefinedFeatures = null; + private Collection redefinedFeatures = null; + private EList featureMembership = null; public void clearCaches() { super.clearCaches(); inheritedMembership = null; nonPrivateMembership = null; redefinedFeatures = null; + featureMembership = null; } // Implicit Elements diff --git a/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java b/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java index dc5046a9f0..3c28dd21d4 100644 --- a/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java +++ b/org.omg.sysml/src/org/omg/sysml/delegate/setting/Type_featureMembership_SettingDelegate.java @@ -1,7 +1,7 @@ /******************************************************************************* * SysML 2 Pilot Implementation * Copyright (c) 2022 Siemens AG - * Copyright (c) 2022 Model Driven Solutions, Inc. + * Copyright (c) 2022, 2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -22,13 +22,11 @@ package org.omg.sysml.delegate.setting; -import java.util.List; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; -import org.omg.sysml.lang.sysml.FeatureMembership; import org.omg.sysml.lang.sysml.Type; -import org.omg.sysml.util.NonNotifyingEObjectEList; +import org.omg.sysml.util.TypeUtil; public class Type_featureMembership_SettingDelegate extends BasicDerivedListSettingDelegate { @@ -38,18 +36,7 @@ public Type_featureMembership_SettingDelegate(EStructuralFeature eStructuralFeat @Override protected EList basicGet(InternalEObject owner) { - Type self = (Type)owner; - - EList featureMemberships = new NonNotifyingEObjectEList<>(FeatureMembership.class, owner, eStructuralFeature.getFeatureID()); - featureMemberships.addAll(self.getOwnedFeatureMembership()); - // For improved performance, compute supertypes only once. - List allSupertypes = self.allSupertypes(); - self.getInheritedMembership().stream(). - filter(FeatureMembership.class::isInstance). - map(FeatureMembership.class::cast). - filter(membership->allSupertypes.contains(membership.getOwningType())). - forEachOrdered(featureMemberships::add); - return featureMemberships; + return TypeUtil.getFeatureMembershipOf((Type)owner); } } diff --git a/org.omg.sysml/src/org/omg/sysml/util/TypeUtil.java b/org.omg.sysml/src/org/omg/sysml/util/TypeUtil.java index af380fe87e..5d31254a5d 100644 --- a/org.omg.sysml/src/org/omg/sysml/util/TypeUtil.java +++ b/org.omg.sysml/src/org/omg/sysml/util/TypeUtil.java @@ -1,6 +1,6 @@ /******************************************************************************* * SysML 2 Pilot Implementation - * Copyright (c) 2021-2022, 2024-2025 Model Driven Solutions, Inc. + * Copyright (c) 2021-2022, 2024-2026 Model Driven Solutions, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -104,6 +104,10 @@ public static List getFeaturesRedefinedBy(Type type, Feature skip) { flatMap(feature->FeatureUtil.getRedefinedFeaturesWithComputedOf(feature).stream()). toList(); } + + public static EList getFeatureMembershipOf(Type type) { + return getTypeAdapter(type).getFeatureMembership(); + } // Supertypes