diff --git a/org.omg.sysml.interactive.tests/META-INF/MANIFEST.MF b/org.omg.sysml.interactive.tests/META-INF/MANIFEST.MF index 616c070a38..bc16cea929 100644 --- a/org.omg.sysml.interactive.tests/META-INF/MANIFEST.MF +++ b/org.omg.sysml.interactive.tests/META-INF/MANIFEST.MF @@ -13,4 +13,5 @@ Require-Bundle: org.omg.sysml.interactive;bundle-version="0.62.0", org.omg.sysml;bundle-version="0.62.0", org.eclipse.xtext;bundle-version="2.22.0", org.omg.kerml.xtext;bundle-version="0.62.0", - org.omg.sysml.xtext;bundle-version="0.62.0" + org.omg.sysml.xtext;bundle-version="0.62.0", + org.omg.kerml.xpect.tests;bundle-version="0.62.0" diff --git a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ParserPostProcessorTest.java b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ParserPostProcessorTest.java index 7ee12a749f..24b7c2d81e 100644 --- a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ParserPostProcessorTest.java +++ b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/ParserPostProcessorTest.java @@ -12,35 +12,42 @@ package org.omg.sysml.interactive.tests; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; +import java.util.List; + +import org.eclipse.emf.ecore.EClass; import org.junit.Test; import org.omg.kerml.xtext.postprocessing.ElementParserPostProcessor; import org.omg.kerml.xtext.postprocessing.ImportParserPostProcessor; import org.omg.kerml.xtext.postprocessing.LiteralStringParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.ConnectionUsageParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.ItemUsageParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.OccurrenceUsageParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.PartUsageParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.PortUsageParserPostProcessor; -import org.omg.sysml.xtext.postprocessing.SysMLParserPostProcessorFactory; import org.omg.kerml.xtext.postprocessing.RedefinitionParserPostProcessor; import org.omg.sysml.lang.sysml.ConnectionUsage; import org.omg.sysml.lang.sysml.Element; import org.omg.sysml.lang.sysml.Feature; import org.omg.sysml.lang.sysml.FeatureDirectionKind; +import org.omg.sysml.lang.sysml.FeatureMembership; import org.omg.sysml.lang.sysml.LiteralString; import org.omg.sysml.lang.sysml.OccurrenceUsage; import org.omg.sysml.lang.sysml.OwningMembership; +import org.omg.sysml.lang.sysml.PartDefinition; import org.omg.sysml.lang.sysml.PartUsage; +import org.omg.sysml.lang.sysml.PortDefinition; import org.omg.sysml.lang.sysml.PortUsage; import org.omg.sysml.lang.sysml.PortionKind; import org.omg.sysml.lang.sysml.SysMLFactory; +import org.omg.sysml.lang.sysml.SysMLPackage; import org.omg.sysml.lang.sysml.Usage; import org.omg.sysml.util.TypeUtil; +import org.omg.sysml.xtext.postprocessing.ConnectionUsageParserPostProcessor; +import org.omg.sysml.xtext.postprocessing.ItemUsageParserPostProcessor; +import org.omg.sysml.xtext.postprocessing.OccurrenceUsageParserPostProcessor; +import org.omg.sysml.xtext.postprocessing.PartUsageParserPostProcessor; +import org.omg.sysml.xtext.postprocessing.PortUsageParserPostProcessor; +import org.omg.sysml.xtext.postprocessing.SysMLParserPostProcessorFactory; public class ParserPostProcessorTest extends SysMLInteractiveTest { @@ -170,4 +177,83 @@ public void postProcessMakesUsageOutsideFeatureMembershipNonComposite() { assertFalse(usage.isComposite()); } + + @Test + public void standardFactoryUsesTheEcoreCompositeDefault() { + assertFalse(SysMLFactory.eINSTANCE.createUsage().isComposite()); + for (EClass eClass : nonCompositeUsageTypes()) { + Usage usage = (Usage)SysMLFactory.eINSTANCE.create(eClass); + assertFalse(eClass.getName(), usage.isComposite()); + assertTrue(eClass.getName(), usage.isReference()); + } + } + + @Test + public void parserAdapterRestoresImplicitConstructorDefaults() { + PartUsage partUsage = (PartUsage)createUsageOwnedByFeatureMembership(SysMLPackage.Literals.PART_USAGE); + postProcess(partUsage); + assertTrue(partUsage.isComposite()); + + for (EClass eClass : nonCompositeUsageTypes()) { + Usage usage = createUsageOwnedByFeatureMembership(eClass); + postProcess(usage); + assertFalse(eClass.getName(), usage.isComposite()); + assertTrue(eClass.getName(), usage.isReference()); + } + } + + @Test + public void postProcessMakesContextuallyReferentialUsagesNonComposite() { + PartUsage directedUsage = (PartUsage)createUsageOwnedByFeatureMembership(SysMLPackage.Literals.PART_USAGE); + directedUsage.setDirection(FeatureDirectionKind.IN); + postProcess(directedUsage); + assertFalse(directedUsage.isComposite()); + + PartUsage endUsage = (PartUsage)createUsageOwnedByFeatureMembership(SysMLPackage.Literals.PART_USAGE); + endUsage.setIsEnd(true); + postProcess(endUsage); + assertFalse(endUsage.isComposite()); + + PartUsage unfeaturedUsage = SysMLFactory.eINSTANCE.createPartUsage(); + OwningMembership membership = SysMLFactory.eINSTANCE.createOwningMembership(); + membership.setOwnedMemberElement(unfeaturedUsage); + postProcess(unfeaturedUsage); + assertFalse(unfeaturedUsage.isComposite()); + } + + @Test + public void portUsageIsCompositeOnlyInAPortContext() { + PortUsage portUsage = SysMLFactory.eINSTANCE.createPortUsage(); + FeatureMembership membership = SysMLFactory.eINSTANCE.createFeatureMembership(); + membership.setOwnedMemberFeature(portUsage); + PortDefinition owner = SysMLFactory.eINSTANCE.createPortDefinition(); + owner.getOwnedRelationship().add(membership); + postProcess(portUsage); + assertTrue(portUsage.isComposite()); + + PortUsage partPortUsage = (PortUsage)createUsageOwnedByFeatureMembership(SysMLPackage.Literals.PORT_USAGE); + postProcess(partPortUsage); + assertFalse(partPortUsage.isComposite()); + } + + private static List nonCompositeUsageTypes() { + return List.of( + SysMLPackage.Literals.ATTRIBUTE_USAGE, + SysMLPackage.Literals.BINDING_CONNECTOR_AS_USAGE, + SysMLPackage.Literals.EVENT_OCCURRENCE_USAGE, + SysMLPackage.Literals.EXHIBIT_STATE_USAGE, + SysMLPackage.Literals.INCLUDE_USE_CASE_USAGE, + SysMLPackage.Literals.PERFORM_ACTION_USAGE, + SysMLPackage.Literals.REFERENCE_USAGE, + SysMLPackage.Literals.SUCCESSION_AS_USAGE); + } + + private static Usage createUsageOwnedByFeatureMembership(EClass eClass) { + Usage usage = (Usage)SysMLFactory.eINSTANCE.create(eClass); + FeatureMembership membership = SysMLFactory.eINSTANCE.createFeatureMembership(); + membership.setOwnedMemberFeature(usage); + PartDefinition owner = SysMLFactory.eINSTANCE.createPartDefinition(); + owner.getOwnedRelationship().add(membership); + return usage; + } } diff --git a/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/UsageParsingTest.java b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/UsageParsingTest.java new file mode 100644 index 0000000000..b48847ebbc --- /dev/null +++ b/org.omg.sysml.interactive.tests/src/org/omg/sysml/interactive/tests/UsageParsingTest.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Obeo + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ + +package org.omg.sysml.interactive.tests; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +import org.eclipse.emf.common.util.TreeIterator; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.resource.XtextResourceSet; +import org.junit.BeforeClass; +import org.junit.Test; +import org.omg.kerml.xpect.KerMLXtextTests; +import org.omg.sysml.lang.sysml.SysMLFactory; +import org.omg.sysml.lang.sysml.SysMLPackage; +import org.omg.sysml.lang.sysml.Usage; +import org.omg.sysml.xtext.SysMLStandaloneSetup; + +import com.google.inject.Injector; + +public class UsageParsingTest { + + private static Injector injector; + + @BeforeClass + public static void setUp() { + KerMLXtextTests.setup(); + injector = new SysMLStandaloneSetup().createInjectorAndDoEMFRegistration(); + SysMLPackage.eINSTANCE.eClass(); + } + + @Test + public void parserUsesSyntaxNodesToApplyCompositeDefaults() throws IOException { + XtextResource resource = parse(""" + part def P { + part implicitComposite; + ref part explicitReference; + in part directed; + attribute nonCompositeType; + } + action def A { + merge explicitComposite; + } + """); + + Usage implicitComposite = findUsage(resource, "implicitComposite"); + assertTrue(NodeModelUtils.findNodesForFeature( + implicitComposite, SysMLPackage.Literals.FEATURE__IS_COMPOSITE).isEmpty()); + assertTrue(NodeModelUtils.findNodesForFeature( + implicitComposite, SysMLPackage.Literals.USAGE__IS_REFERENCE).isEmpty()); + assertTrue(implicitComposite.isComposite()); + + Usage explicitReference = findUsage(resource, "explicitReference"); + assertFalse(NodeModelUtils.findNodesForFeature( + explicitReference, SysMLPackage.Literals.USAGE__IS_REFERENCE).isEmpty()); + assertTrue(explicitReference.isReference()); + + Usage explicitComposite = findUsage(resource, "explicitComposite"); + assertFalse(NodeModelUtils.findNodesForFeature( + explicitComposite, SysMLPackage.Literals.FEATURE__IS_COMPOSITE).isEmpty()); + assertTrue(explicitComposite.isComposite()); + + assertTrue(findUsage(resource, "directed").isReference()); + assertTrue(findUsage(resource, "nonCompositeType").isReference()); + } + + @Test + public void compositeValuesSurviveXmiRoundTrips() throws IOException { + assertXmiRoundTrip(false); + assertXmiRoundTrip(true); + + Usage usage = SysMLFactory.eINSTANCE.createUsage(); + usage.setIsComposite(true); + usage.eUnset(SysMLPackage.Literals.FEATURE__IS_COMPOSITE); + Usage loaded = xmiRoundTrip(usage); + assertFalse(loaded.isComposite()); + assertTrue(loaded.isReference()); + } + + private static XtextResource parse(String text) throws IOException { + XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class); + XtextResource resource = (XtextResource)resourceSet.createResource(URI.createURI("memory:/usage.sysml")); + resource.load(new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)), Map.of()); + EcoreUtil.resolveAll(resource); + assertTrue(resource.getErrors().toString(), resource.getErrors().isEmpty()); + return resource; + } + + private static Usage findUsage(Resource resource, String name) { + TreeIterator iterator = resource.getAllContents(); + while (iterator.hasNext()) { + EObject object = iterator.next(); + if (object instanceof Usage usage && name.equals(usage.getDeclaredName())) { + return usage; + } + } + fail("Usage not found: " + name); + return null; + } + + private static void assertXmiRoundTrip(boolean isComposite) throws IOException { + Usage usage = SysMLFactory.eINSTANCE.createUsage(); + usage.setIsComposite(isComposite); + Usage loaded = xmiRoundTrip(usage); + if (isComposite) { + assertTrue(loaded.isComposite()); + assertFalse(loaded.isReference()); + } else { + assertFalse(loaded.isComposite()); + assertTrue(loaded.isReference()); + } + } + + private static Usage xmiRoundTrip(Usage usage) throws IOException { + URI uri = URI.createURI("memory:/usage.xmi"); + Resource savedResource = new XMIResourceImpl(uri); + savedResource.getContents().add(usage); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + savedResource.save(output, Map.of()); + + Resource loadedResource = new XMIResourceImpl(uri); + loadedResource.load(new ByteArrayInputStream(output.toByteArray()), Map.of()); + return (Usage)loadedResource.getContents().get(0); + } +} diff --git a/org.omg.sysml.logic.bundle/lib/org.omg.sysml.logic-0.62.0-SNAPSHOT.jar b/org.omg.sysml.logic.bundle/lib/org.omg.sysml.logic-0.62.0-SNAPSHOT.jar index 2b7ec9ef06..bba4e5bddb 100644 Binary files a/org.omg.sysml.logic.bundle/lib/org.omg.sysml.logic-0.62.0-SNAPSHOT.jar and b/org.omg.sysml.logic.bundle/lib/org.omg.sysml.logic-0.62.0-SNAPSHOT.jar differ diff --git a/org.omg.sysml.model.bundle/lib/org.omg.sysml.model-0.62.0-SNAPSHOT.jar b/org.omg.sysml.model.bundle/lib/org.omg.sysml.model-0.62.0-SNAPSHOT.jar index 9ac46e96fa..811240f6c6 100644 Binary files a/org.omg.sysml.model.bundle/lib/org.omg.sysml.model-0.62.0-SNAPSHOT.jar and b/org.omg.sysml.model.bundle/lib/org.omg.sysml.model-0.62.0-SNAPSHOT.jar differ diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/AttributeUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/AttributeUsageImpl.java index 78ef9eb4e0..5500affdef 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/AttributeUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/AttributeUsageImpl.java @@ -41,11 +41,10 @@ public class AttributeUsageImpl extends UsageImpl implements AttributeUsage { /** * * - * @generated NOT + * @generated */ protected AttributeUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/BindingConnectorAsUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/BindingConnectorAsUsageImpl.java index 2633ecc2e7..875305eb4f 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/BindingConnectorAsUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/BindingConnectorAsUsageImpl.java @@ -18,11 +18,10 @@ public class BindingConnectorAsUsageImpl extends ConnectorAsUsageImpl implements /** * * - * @generated NOT + * @generated */ protected BindingConnectorAsUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/EventOccurrenceUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/EventOccurrenceUsageImpl.java index 8cc3819e6e..5517c718d2 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/EventOccurrenceUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/EventOccurrenceUsageImpl.java @@ -36,11 +36,10 @@ public class EventOccurrenceUsageImpl extends OccurrenceUsageImpl implements Eve /** * * - * @generated NOT + * @generated */ protected EventOccurrenceUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ExhibitStateUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ExhibitStateUsageImpl.java index fc4388651c..1e6047abef 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ExhibitStateUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ExhibitStateUsageImpl.java @@ -40,11 +40,10 @@ public class ExhibitStateUsageImpl extends StateUsageImpl implements ExhibitStat /** * * - * @generated NOT + * @generated */ protected ExhibitStateUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/IncludeUseCaseUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/IncludeUseCaseUsageImpl.java index 796c16e823..3df96f3cf5 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/IncludeUseCaseUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/IncludeUseCaseUsageImpl.java @@ -40,11 +40,10 @@ public class IncludeUseCaseUsageImpl extends UseCaseUsageImpl implements Include /** * * - * @generated NOT + * @generated */ protected IncludeUseCaseUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/PerformActionUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/PerformActionUsageImpl.java index 26860112cb..996cae55a7 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/PerformActionUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/PerformActionUsageImpl.java @@ -38,11 +38,10 @@ public class PerformActionUsageImpl extends ActionUsageImpl implements PerformAc /** * * - * @generated NOT + * @generated */ protected PerformActionUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ReferenceUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ReferenceUsageImpl.java index 953072bed9..ac8612eeea 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ReferenceUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/ReferenceUsageImpl.java @@ -18,11 +18,10 @@ public class ReferenceUsageImpl extends UsageImpl implements ReferenceUsage { /** * * - * @generated NOT + * @generated */ protected ReferenceUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/SuccessionAsUsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/SuccessionAsUsageImpl.java index f9e025129c..4650ae18a6 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/SuccessionAsUsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/SuccessionAsUsageImpl.java @@ -18,11 +18,10 @@ public class SuccessionAsUsageImpl extends ConnectorAsUsageImpl implements Succe /** * * - * @generated NOT + * @generated */ protected SuccessionAsUsageImpl() { super(); - isComposite = false; } /** diff --git a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/UsageImpl.java b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/UsageImpl.java index 3b84cb35b8..690f9e773c 100644 --- a/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/UsageImpl.java +++ b/org.omg.sysml.model/src/main/java/org/omg/sysml/lang/sysml/impl/UsageImpl.java @@ -484,11 +484,10 @@ public class UsageImpl extends FeatureImpl implements Usage { /** * * - * @generated NOT + * @generated */ protected UsageImpl() { super(); - isComposite = true; } /** diff --git a/org.omg.sysml.xtext/src/org/omg/sysml/xtext/postprocessing/UsageParserPostProcessor.java b/org.omg.sysml.xtext/src/org/omg/sysml/xtext/postprocessing/UsageParserPostProcessor.java index 76de2ac0e9..9616c6c72c 100644 --- a/org.omg.sysml.xtext/src/org/omg/sysml/xtext/postprocessing/UsageParserPostProcessor.java +++ b/org.omg.sysml.xtext/src/org/omg/sysml/xtext/postprocessing/UsageParserPostProcessor.java @@ -11,19 +11,34 @@ package org.omg.sysml.xtext.postprocessing; +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.xtext.nodemodel.util.NodeModelUtils; import org.omg.kerml.xtext.postprocessing.FeatureParserPostProcessor; import org.omg.sysml.lang.sysml.AttributeDefinition; import org.omg.sysml.lang.sysml.AttributeUsage; +import org.omg.sysml.lang.sysml.SysMLPackage; import org.omg.sysml.lang.sysml.Type; import org.omg.sysml.lang.sysml.Usage; import org.omg.sysml.util.UsageUtil; public class UsageParserPostProcessor extends FeatureParserPostProcessor { + private static final List NON_COMPOSITE_USAGE_TYPES = List.of( + SysMLPackage.Literals.ATTRIBUTE_USAGE, + SysMLPackage.Literals.BINDING_CONNECTOR_AS_USAGE, + SysMLPackage.Literals.EVENT_OCCURRENCE_USAGE, + SysMLPackage.Literals.EXHIBIT_STATE_USAGE, + SysMLPackage.Literals.INCLUDE_USE_CASE_USAGE, + SysMLPackage.Literals.PERFORM_ACTION_USAGE, + SysMLPackage.Literals.REFERENCE_USAGE, + SysMLPackage.Literals.SUCCESSION_AS_USAGE); + public UsageParserPostProcessor(Usage element) { super(element); } - + @Override public Usage getTarget() { return (Usage)super.getTarget(); @@ -33,7 +48,8 @@ public Usage getTarget() { public void postProcess () { super.postProcess(); Usage target = getTarget(); - if (target.isVariation()) { + setIsCompositeIfUnset(target); + if (target.isVariation()) { target.setIsAbstract(true); } Type featuringType = UsageUtil.getExpectedFeaturingTypeOf(target); @@ -43,6 +59,20 @@ public void postProcess () { } } + private void setIsCompositeIfUnset(Usage target) { + boolean isCompositeSet = !NodeModelUtils.findNodesForFeature( + target, SysMLPackage.Literals.FEATURE__IS_COMPOSITE).isEmpty(); + boolean isReferenceSet = !NodeModelUtils.findNodesForFeature( + target, SysMLPackage.Literals.USAGE__IS_REFERENCE).isEmpty(); + if (!isCompositeSet && !isReferenceSet) { + target.setIsComposite(isCompositeByDefault(target.eClass())); + } + } + + private static boolean isCompositeByDefault(EClass eClass) { + return NON_COMPOSITE_USAGE_TYPES.stream().noneMatch(type -> type.isSuperTypeOf(eClass)); + } + @Override protected void setIsVariableIfConstant() { }