Skip to content
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 @@ -45,11 +45,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;

Expand Down Expand Up @@ -354,6 +356,36 @@ public void testLocale() throws Exception {
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<Element> elements = ((Namespace)root).getOwnedMember();
List<Element> 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));

public final String crossFeatureTest =
"package Test {"
+ " part def A {"
Expand Down
23 changes: 22 additions & 1 deletion org.omg.sysml/src/org/omg/sysml/adapter/TypeAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -202,18 +203,38 @@ protected Collection<Feature> getFeaturesRedefinedByType() {
}
return redefinedFeatures;
}

public EList<FeatureMembership> getFeatureMembership() {
if (featureMembership == null) {
Type target = getTarget();
EList<FeatureMembership> featureMemberships = new NonNotifyingEObjectEList<FeatureMembership>(FeatureMembership.class, (InternalEObject) target, SysMLPackage.TYPE__FEATURE_MEMBERSHIP);
featureMemberships.addAll(target.getOwnedFeatureMembership());
// For improved performance, compute supertypes only once.
List<Type> 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<Membership> inheritedMembership = null;
private EList<Membership> nonPrivateMembership = null;
private Collection<Feature> redefinedFeatures = null;
private Collection<Feature> redefinedFeatures = null;
private EList<FeatureMembership> featureMembership = null;

public void clearCaches() {
super.clearCaches();
inheritedMembership = null;
nonPrivateMembership = null;
redefinedFeatures = null;
featureMembership = null;
}

// Implicit Elements
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -25,9 +25,8 @@
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 {

Expand All @@ -37,13 +36,7 @@ public Type_featureMembership_SettingDelegate(EStructuralFeature eStructuralFeat

@Override
protected EList<?> basicGet(InternalEObject owner) {
EList<FeatureMembership> featureMemberships = new NonNotifyingEObjectEList<>(FeatureMembership.class, owner, eStructuralFeature.getFeatureID());
featureMemberships.addAll(((Type)owner).getOwnedFeatureMembership());
((Type)owner).getInheritedMembership().stream().
filter(FeatureMembership.class::isInstance).
map(FeatureMembership.class::cast).
forEachOrdered(featureMemberships::add);
return featureMemberships;
return TypeUtil.getFeatureMembershipOf((Type)owner);
}

}
6 changes: 5 additions & 1 deletion org.omg.sysml/src/org/omg/sysml/util/TypeUtil.java
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -104,6 +104,10 @@ public static List<Feature> getFeaturesRedefinedBy(Type type, Feature skip) {
flatMap(feature->FeatureUtil.getRedefinedFeaturesWithComputedOf(feature).stream()).
toList();
}

public static EList<FeatureMembership> getFeatureMembershipOf(Type type) {
return getTypeAdapter(type).getFeatureMembership();
}

// Supertypes

Expand Down
Loading