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 @@ -327,7 +327,31 @@ public boolean isImplicitSpecializationDeclaredFor(EClass eClass) {
}

public boolean isImplicitSpecializationFor(EClass eClass, Type general) {
return implicitGeneralTypes.getOrDefault(eClass, Collections.emptyList()).contains(general);
return implicitGeneralTypes.getOrDefault(eClass, Collections.emptyList()).stream().
anyMatch(existingGeneral->areEquivalentImplicitGeneralTypes(existingGeneral, general));
}

/**
* Feature chains are derived Types for which object identity is not sufficient:
* two independently created chains may represent the same ordered sequence of
* chaining Features.
*/
protected static boolean areEquivalentImplicitGeneralTypes(Type first, Type second) {
if (first == second) {
return true;
} else if (first instanceof Feature && second instanceof Feature) {
List<Feature> firstChain = ((Feature)first).getChainingFeature();
List<Feature> secondChain = ((Feature)second).getChainingFeature();
if (!firstChain.isEmpty() && firstChain.size() == secondChain.size()) {
for (int i = 0; i < firstChain.size(); i++) {
if (firstChain.get(i) != secondChain.get(i)) {
return false;
}
}
return true;
}
}
return false;
}

protected static boolean hasNoConformingSpecializations(Type type, Class<?> kind, Type defaultGeneral) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,26 @@

package org.omg.sysml.logic;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import java.util.List;

import org.junit.Test;
import org.omg.sysml.lang.sysml.AcceptActionUsage;
import org.omg.sysml.lang.sysml.Feature;
import org.omg.sysml.lang.sysml.FeatureDirectionKind;
import org.omg.sysml.lang.sysml.ParameterMembership;
import org.omg.sysml.lang.sysml.ReferenceUsage;
import org.omg.sysml.lang.sysml.SysMLFactory;
import org.omg.sysml.lang.sysml.SysMLPackage;
import org.omg.sysml.lang.sysml.TransitionFeatureKind;
import org.omg.sysml.lang.sysml.TransitionFeatureMembership;
import org.omg.sysml.lang.sysml.TransitionUsage;
import org.omg.sysml.lang.sysml.Type;
import org.omg.sysml.util.FeatureUtil;
import org.omg.sysml.util.TypeUtil;

/**
* Tests transition derived-property computations.
Expand All @@ -54,4 +65,44 @@ public void transitionSourceDerivationIsReentrantSafeWithoutSuccession() {
transition.getOwnedRelationship().add(parameterMembership);
assertNull(transition.getSource());
}

/**
* A structurally equivalent feature chain already registered as an implicit
* Subsetting must not be duplicated when the transition payload default
* general type is computed.
*/
@Test
public void transitionPayloadDoesNotDuplicateEquivalentImplicitSubsetting() {
SysMLLogicStandaloneSetup.doSetup();
SysMLPackage.eINSTANCE.eClass();
SysMLFactory factory = SysMLFactory.eINSTANCE;
TransitionUsage transition = factory.createTransitionUsage();
addParameter(transition, factory.createReferenceUsage());
ReferenceUsage transitionPayload = factory.createReferenceUsage();
addParameter(transition, transitionPayload);

AcceptActionUsage trigger = factory.createAcceptActionUsage();
ReferenceUsage triggerPayload = factory.createReferenceUsage();
addParameter(trigger, triggerPayload);
TransitionFeatureMembership triggerMembership = factory.createTransitionFeatureMembership();
triggerMembership.setKind(TransitionFeatureKind.TRIGGER);
triggerMembership.getOwnedRelatedElement().add(trigger);
transition.getOwnedRelationship().add(triggerMembership);

Feature existingChain = FeatureUtil.chainFeatures(trigger, triggerPayload);
TypeUtil.addImplicitGeneralTypeTo(transitionPayload, SysMLPackage.Literals.SUBSETTING, existingChain);

TypeUtil.getImplicitGeneralTypesFor(transitionPayload);

List<Type> implicitSubsettings = TypeUtil.getImplicitGeneralTypesOnly(transitionPayload, SysMLPackage.Literals.SUBSETTING);
assertEquals(1, implicitSubsettings.size());
assertSame(existingChain, implicitSubsettings.get(0));
}

private static void addParameter(Type owner, Feature parameter) {
parameter.setDirection(FeatureDirectionKind.IN);
ParameterMembership membership = SysMLFactory.eINSTANCE.createParameterMembership();
membership.setOwnedMemberParameter(parameter);
owner.getOwnedRelationship().add(membership);
}
}
Loading