Skip to content

Commit 13c32ea

Browse files
authored
Merge pull request #792 from Systems-Modeling/ST6RI-961
ST6RI-961 There can be duplicate implicit Subsettings for structurally equivalent feature chains
2 parents b6674f5 + 3ce6768 commit 13c32ea

2 files changed

Lines changed: 76 additions & 1 deletion

File tree

org.omg.sysml.logic/src/main/java/org/omg/sysml/adapter/TypeAdapter.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,31 @@ public boolean isImplicitSpecializationDeclaredFor(EClass eClass) {
327327
}
328328

329329
public boolean isImplicitSpecializationFor(EClass eClass, Type general) {
330-
return implicitGeneralTypes.getOrDefault(eClass, Collections.emptyList()).contains(general);
330+
return implicitGeneralTypes.getOrDefault(eClass, Collections.emptyList()).stream().
331+
anyMatch(existingGeneral->areEquivalentImplicitGeneralTypes(existingGeneral, general));
332+
}
333+
334+
/**
335+
* Feature chains are derived Types for which object identity is not sufficient:
336+
* two independently created chains may represent the same ordered sequence of
337+
* chaining Features.
338+
*/
339+
protected static boolean areEquivalentImplicitGeneralTypes(Type first, Type second) {
340+
if (first == second) {
341+
return true;
342+
} else if (first instanceof Feature && second instanceof Feature) {
343+
List<Feature> firstChain = ((Feature)first).getChainingFeature();
344+
List<Feature> secondChain = ((Feature)second).getChainingFeature();
345+
if (!firstChain.isEmpty() && firstChain.size() == secondChain.size()) {
346+
for (int i = 0; i < firstChain.size(); i++) {
347+
if (firstChain.get(i) != secondChain.get(i)) {
348+
return false;
349+
}
350+
}
351+
return true;
352+
}
353+
}
354+
return false;
331355
}
332356

333357
protected static boolean hasNoConformingSpecializations(Type type, Class<?> kind, Type defaultGeneral) {

org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/TransitionUsageAdapterTest.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,26 @@
2121

2222
package org.omg.sysml.logic;
2323

24+
import static org.junit.Assert.assertEquals;
2425
import static org.junit.Assert.assertNull;
26+
import static org.junit.Assert.assertSame;
27+
28+
import java.util.List;
2529

2630
import org.junit.Test;
31+
import org.omg.sysml.lang.sysml.AcceptActionUsage;
2732
import org.omg.sysml.lang.sysml.Feature;
2833
import org.omg.sysml.lang.sysml.FeatureDirectionKind;
2934
import org.omg.sysml.lang.sysml.ParameterMembership;
35+
import org.omg.sysml.lang.sysml.ReferenceUsage;
3036
import org.omg.sysml.lang.sysml.SysMLFactory;
3137
import org.omg.sysml.lang.sysml.SysMLPackage;
38+
import org.omg.sysml.lang.sysml.TransitionFeatureKind;
39+
import org.omg.sysml.lang.sysml.TransitionFeatureMembership;
3240
import org.omg.sysml.lang.sysml.TransitionUsage;
41+
import org.omg.sysml.lang.sysml.Type;
42+
import org.omg.sysml.util.FeatureUtil;
43+
import org.omg.sysml.util.TypeUtil;
3344

3445
/**
3546
* Tests transition derived-property computations.
@@ -54,4 +65,44 @@ public void transitionSourceDerivationIsReentrantSafeWithoutSuccession() {
5465
transition.getOwnedRelationship().add(parameterMembership);
5566
assertNull(transition.getSource());
5667
}
68+
69+
/**
70+
* A structurally equivalent feature chain already registered as an implicit
71+
* Subsetting must not be duplicated when the transition payload default
72+
* general type is computed.
73+
*/
74+
@Test
75+
public void transitionPayloadDoesNotDuplicateEquivalentImplicitSubsetting() {
76+
SysMLLogicStandaloneSetup.doSetup();
77+
SysMLPackage.eINSTANCE.eClass();
78+
SysMLFactory factory = SysMLFactory.eINSTANCE;
79+
TransitionUsage transition = factory.createTransitionUsage();
80+
addParameter(transition, factory.createReferenceUsage());
81+
ReferenceUsage transitionPayload = factory.createReferenceUsage();
82+
addParameter(transition, transitionPayload);
83+
84+
AcceptActionUsage trigger = factory.createAcceptActionUsage();
85+
ReferenceUsage triggerPayload = factory.createReferenceUsage();
86+
addParameter(trigger, triggerPayload);
87+
TransitionFeatureMembership triggerMembership = factory.createTransitionFeatureMembership();
88+
triggerMembership.setKind(TransitionFeatureKind.TRIGGER);
89+
triggerMembership.getOwnedRelatedElement().add(trigger);
90+
transition.getOwnedRelationship().add(triggerMembership);
91+
92+
Feature existingChain = FeatureUtil.chainFeatures(trigger, triggerPayload);
93+
TypeUtil.addImplicitGeneralTypeTo(transitionPayload, SysMLPackage.Literals.SUBSETTING, existingChain);
94+
95+
TypeUtil.getImplicitGeneralTypesFor(transitionPayload);
96+
97+
List<Type> implicitSubsettings = TypeUtil.getImplicitGeneralTypesOnly(transitionPayload, SysMLPackage.Literals.SUBSETTING);
98+
assertEquals(1, implicitSubsettings.size());
99+
assertSame(existingChain, implicitSubsettings.get(0));
100+
}
101+
102+
private static void addParameter(Type owner, Feature parameter) {
103+
parameter.setDirection(FeatureDirectionKind.IN);
104+
ParameterMembership membership = SysMLFactory.eINSTANCE.createParameterMembership();
105+
membership.setOwnedMemberParameter(parameter);
106+
owner.getOwnedRelationship().add(membership);
107+
}
57108
}

0 commit comments

Comments
 (0)