Skip to content

Commit ee7402c

Browse files
adaussyAxelRICHARD
authored andcommitted
[1998] Add Implicit TypeFeaturing
Bug: #1998 Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr>
1 parent 4d9f0aa commit ee7402c

4 files changed

Lines changed: 99 additions & 2 deletions

File tree

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ For example `ViewUsage` elements are no longer rendered in _parts_ compartments.
4343
- https://github.com/eclipse-syson/syson/issues/1949[#1949] [diagrams] Allow redefining a `PartUsage` with the same name as the redefined usage.
4444
- https://github.com/eclipse-syson/syson/issues/1863[#1863] [diagrams] Dropping an elements on a diagram which is already visible gives feedback again.
4545
- https://github.com/eclipse-syson/syson/issues/2026[#2026] [explorer] Fix an issue where creating a new model using the _Create a new model_ action in the _Explorer_ view was not adding the ".sysml" extension to the model name.
46+
- https://github.com/eclipse-syson/syson/issues/1998[#1998] [metamodel] Missing implicit TypeFeaturing.
4647

4748
=== Improvements
4849

backend/metamodel/syson-sysml-metamodel/src/main/java/org/eclipse/syson/sysml/impl/FeatureImpl.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@
4545
import org.eclipse.syson.sysml.OwningMembership;
4646
import org.eclipse.syson.sysml.Redefinition;
4747
import org.eclipse.syson.sysml.ReferenceSubsetting;
48+
import org.eclipse.syson.sysml.Specialization;
4849
import org.eclipse.syson.sysml.Subsetting;
50+
import org.eclipse.syson.sysml.SysmlFactory;
4951
import org.eclipse.syson.sysml.SysmlPackage;
5052
import org.eclipse.syson.sysml.Type;
5153
import org.eclipse.syson.sysml.TypeFeaturing;
54+
import org.eclipse.syson.sysml.util.ILibraryNamespaceProvider;
55+
import org.eclipse.syson.sysml.util.LibraryNamespaceProvider;
5256

5357
/**
5458
* <!-- begin-user-doc --> An implementation of the model object '<em><b>Feature</b></em>'. <!-- end-user-doc -->
@@ -462,6 +466,13 @@ public EList<Type> getFeaturingType() {
462466
if (!chainingFeature.isEmpty()) {
463467
featuringTypes.addAll(chainingFeature.get(0).getFeaturingType());
464468
}
469+
470+
// Add implicit featuring type
471+
Type implicitType = this.computeImplicitFeaturingType();
472+
if (implicitType != null) {
473+
featuringTypes.add(implicitType);
474+
}
475+
465476
return new EcoreEList.UnmodifiableEList<>(this, SysmlPackage.eINSTANCE.getFeature_FeaturingType(), featuringTypes.size(), featuringTypes.toArray());
466477
}
467478

@@ -1539,4 +1550,59 @@ private Collection<Feature> collectTypingFeatures() {
15391550
}
15401551
return featureCollector;
15411552
}
1553+
1554+
/**
1555+
* @generated NOT
1556+
*/
1557+
private Type computeImplicitFeaturingType() {
1558+
Type owningType = this.getOwningType();
1559+
Type implicitType = null;
1560+
if (owningType != null) {
1561+
1562+
if (!this.isIsVariable()) {
1563+
// KerML 7.3.2.6 “Feature Membership” – “A feature that is declared within the body of a type … automatically has that type as a featuring type.”
1564+
// SysML 8.3.3.1.6 FeatureMembership - If the ownedMemberFeature has isVariable = false, then the FeatureMembership implies that the owningType is also a featuringType of the
1565+
// ownedMemberFeature.
1566+
implicitType = owningType;
1567+
} else {
1568+
// KerML 8.4.4.3
1569+
// Class (or any Type that directly or indirectly specializes Occurrence) may have ownedFeatures with
1570+
// isVariable = true. The checkFeatureFeatureMembershipTypeFeaturing constraint requires that such
1571+
// variable Features are featured by the snapshots of their owningType.
1572+
TypeFeaturing typeFeaturing = SysmlFactory.eINSTANCE.createTypeFeaturing();
1573+
typeFeaturing.setIsImplied(true);
1574+
1575+
// Table 9. Core Semantics Implied Relationships Supporting Kernel Semantics - Note 1
1576+
// For the checkFeatureFeatureMembershipTypeFeaturing constraint, if the Feature has
1577+
//isVariable = false, then the target Type is the owningType of the Feature. If the Feature has
1578+
//isVariable = true and the owningType is the base Class Occurrences::Occurrence, then the
1579+
//target is Occurrences::Occurrence::snapshots (see 9.2.4.2.13 ). Otherwise, the target Type shall
1580+
//be constructed so as to satisfy the constraint and shall be owned as an ownedRelatedElement of the
1581+
//implied TypeFeaturing relationship. For further details, see 8.4.4.3 .
1582+
ILibraryNamespaceProvider nsProvider = LibraryNamespaceProvider.getFrom(this);
1583+
if (nsProvider == null) {
1584+
nsProvider = new LibraryNamespaceProvider(this);
1585+
}
1586+
Type snapshot = nsProvider.getNamespaceFromLibrary("Occurrences::Occurrence::snapshot", Type.class);
1587+
if (owningType == nsProvider.getNamespaceFromLibrary("Occurrences::Occurrence")) {
1588+
implicitType = snapshot;
1589+
} else {
1590+
implicitType = SysmlFactory.eINSTANCE.createFeature();
1591+
typeFeaturing.getOwnedRelatedElement().add(implicitType);
1592+
1593+
Specialization specialization = SysmlFactory.eINSTANCE.createSpecialization();
1594+
implicitType.getOwnedRelationship().add(specialization);
1595+
specialization.setSpecific(implicitType);
1596+
specialization.setGeneral(snapshot);
1597+
}
1598+
1599+
typeFeaturing.setFeaturingType(owningType);
1600+
typeFeaturing.setFeatureOfType((Feature) implicitType);
1601+
implicitType.getOwnedRelationship().add(typeFeaturing);
1602+
1603+
}
1604+
1605+
}
1606+
return implicitType;
1607+
}
15421608
} // FeatureImpl

backend/metamodel/syson-sysml-metamodel/src/test/java/org/eclipse/syson/sysml/impl/FeatureImplTest.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2024 Obeo.
2+
* Copyright (c) 2024, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -12,12 +12,16 @@
1212
*******************************************************************************/
1313
package org.eclipse.syson.sysml.impl;
1414

15-
import static org.junit.Assert.assertNull;
15+
import static org.assertj.core.api.Assertions.assertThat;
1616
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.assertNull;
1718

1819
import org.eclipse.syson.sysml.Feature;
20+
import org.eclipse.syson.sysml.ItemDefinition;
21+
import org.eclipse.syson.sysml.ItemUsage;
1922
import org.eclipse.syson.sysml.util.ModelBuilder;
2023
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.DisplayName;
2125
import org.junit.jupiter.api.Test;
2226

2327
/**
@@ -59,4 +63,22 @@ public void testNames() {
5963
assertEquals("f", f2.effectiveShortName());
6064
}
6165

66+
67+
@Test
68+
@DisplayName("GIVEN a non variable feature in a Type, WHEN computing it's featuring types, THEN the owning type is returned")
69+
public void checkImplicitFeaturingTypeNoVariableFeature() {
70+
var itemDef = this.builder.createWithName(ItemDefinition.class, "ItemDef");
71+
ItemUsage itemUsage = this.builder.createInWithName(ItemUsage.class, itemDef, "ItemUsage");
72+
assertThat(itemUsage.getFeaturingType()).hasSize(1).allMatch(type -> type == itemDef);
73+
}
74+
75+
@Test
76+
@DisplayName("GIVEN a variable feature in a Type, WHEN computing it's featuring types, THEN the owning type is returned")
77+
public void checkImplicitFeaturingTypeVariableFeature() {
78+
var itemDef = this.builder.createWithName(ItemDefinition.class, "ItemDef");
79+
ItemUsage itemUsage = this.builder.createInWithName(ItemUsage.class, itemDef, "ItemUsage");
80+
itemUsage.setIsVariable(true);
81+
assertThat(itemUsage.getFeaturingType()).hasSize(1)
82+
.allMatch(type -> type instanceof Feature feature && feature.getFeaturingType().contains(itemDef));
83+
}
6284
}

doc/content/modules/user-manual/pages/release-notes/2026.3.0.adoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ part system {
7070

7171
** `Req Id` and `Declared Short Name` properties of `RequirementDefinition` and `RequirementUsage` are now synchronized, as required by the SysMLv2 specification.
7272

73+
* In _Validation_ view:
74+
75+
** Improve the computation of _featuringType_ on `Feature` to avoid getting the following validation error:
76+
+
77+
```
78+
If a Feature is owned via a FeatureMembership, then it must have a featuringType for which the operation isFeaturingType returns true. (checkFeatureFeatureMembershipTypeFeaturing constraint on Feature is not respected for Test::MyItemDef::myFeature)
79+
````
80+
7381
== Improvements
7482

7583
* In diagrams:

0 commit comments

Comments
 (0)