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
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- https://github.com/eclipse-syson/syson/issues/1398[#1398] [explorer] Fix an issue where a d'n'd of an `Element` in a diagram exposed the `Element` twice in the `ViewUsage` associated to the diagram.
- https://github.com/eclipse-syson/syson/issues/1411[#1411] [syson] Fix an issue where model and diagrams referencing standard libraries elements might not correctly loaded.
- https://github.com/eclipse-syson/syson/issues/1411[#1411] [syson] Fix an issue where model and diagrams referencing standard libraries elements might not correctly saved.
- https://github.com/eclipse-syson/syson/issues/1407[#1407] [metamodel] Fix an issue where a `Feature` containing a `ChainingFeature` was not typed with the type of the last `ChainingFeature`.

=== Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,25 @@ public List<Specialization> caseFeature(Feature object) {
if (!this.hasRedefinition(object)) {
implicitSpecializations.addAll(this.handleImplicitParameterRedefinition(object));
}
// The specification states that "If the Feature has chainingFeatures, then the union also includes the types of
Comment thread
AxelRICHARD marked this conversation as resolved.
// the last chainingFeature".We need to implement this here in order to make inherited Feature resolvable.
// If we only implement this in "getType" of the Feature implementation the general mechanism of name resolution
// that relies on "getMembership" would fail.
// Normally the implicit typing would be present in the model (either with an implicit inheritance
// or implicit typing). But since in SysON we choose to add those "implicit" element virtually when the derived
// feature are called, we needed to find a place where this 'implicit' typing would impact both Feature.getType
// and Namespace.getMembership. implementations.

EList<Feature> chainingFeature = object.getChainingFeature();
if (!chainingFeature.isEmpty()) {
Feature lastFeature = chainingFeature.get(chainingFeature.size() - 1);
for (Type type : lastFeature.getType()) {
FeatureTyping featureTyping = SysmlFactory.eINSTANCE.createFeatureTyping();
implicitSpecializations.add(featureTyping);
featureTyping.setType(type);
featureTyping.setTypedFeature(object);
}
}
return implicitSpecializations;
}

Expand Down Expand Up @@ -1666,8 +1685,6 @@ private List<Redefinition> handleImplicitParameterRedefinition(Feature feature)
return implicitRedefinitions;
}



private List<Redefinition> handleImplicitParameterRedefinition(Feature feature, Step owner) {
List<Redefinition> implicitRedefinitions = new ArrayList<>();
int parameterIndex = owner.getParameter().indexOf(feature);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -810,18 +810,22 @@ public Type basicGetOwningType() {
}

/**
* <!-- begin-user-doc --> <!-- end-user-doc -->
* <!-- begin-user-doc --> Types that restrict the values of this Feature, such that the values must be instances of
* all the types. The types of a Feature are derived from its typings and the types of its subsettings. If the
* Feature is chained, then the types of the last Feature in the chain are also types of the chained Feature.<!--
* end-user-doc -->
*
* @generated NOT
*/
@Override
public EList<Type> getType() {
List<Type> types = new ArrayList<>();
this.getOwnedRelationship().stream()
this.getOwnedSpecialization().stream()
.filter(FeatureTyping.class::isInstance)
.map(FeatureTyping.class::cast)
.map(typing -> typing.getType())
.forEach(types::add);

return new EcoreEList.UnmodifiableEList<>(this, SysmlPackage.eINSTANCE.getFeature_Type(), types.size(), types.toArray());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ public void setUp() {
end1.getOwnedRelationship().add(featureTypingEnd1);
this.partDef1 = SysmlFactory.eINSTANCE.createPartDefinition();
featureTypingEnd1.setType(this.partDef1);
featureTypingEnd1.setTypedFeature(end1);
var end2 = SysmlFactory.eINSTANCE.createReferenceUsage();
end2.setIsEnd(true);
membershipEnd2.getOwnedRelatedElement().add(end2);
var featureTypingEnd2 = SysmlFactory.eINSTANCE.createFeatureTyping();
end2.getOwnedRelationship().add(featureTypingEnd2);
this.partDef2 = SysmlFactory.eINSTANCE.createPartDefinition();
featureTypingEnd2.setType(this.partDef2);
featureTypingEnd2.setTypedFeature(end2);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ public void setUp() {
end2.getOwnedRelationship().add(featureTypingEnd2);
this.partDef2 = SysmlFactory.eINSTANCE.createPartDefinition();
featureTypingEnd2.setType(this.partDef2);
featureTypingEnd2.setTypedFeature(end2);

this.connectionUsage = SysmlFactory.eINSTANCE.createConnectionUsage();
var featureTypingConnectionUsage = SysmlFactory.eINSTANCE.createFeatureTyping();
featureTypingConnectionUsage.setType(this.connectionDefinition);
featureTypingConnectionUsage.setTypedFeature(this.connectionUsage);
this.connectionUsage.getOwnedRelationship().add(featureTypingConnectionUsage);
var membershipEnd3 = SysmlFactory.eINSTANCE.createFeatureMembership();
var membershipEnd4 = SysmlFactory.eINSTANCE.createFeatureMembership();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2025 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.syson.sysml.impl;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.List;

import org.eclipse.syson.sysml.Feature;
import org.eclipse.syson.sysml.Type;
import org.eclipse.syson.sysml.util.ModelBuilder;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
* Test class for {@link FeatureImpl}.
*
* @author Arthur Daussy
*/
public class FeatureTest {

@DisplayName("GIVEN a Feature with FeatureChain, WHEN computing its features and type, THEN check that type of last ChainingFeature is taking into account for computeing feature type and accessible features.")
@Test
public void checkFeatureChainTypeAndFeatrures() {

ModelBuilder builder = new ModelBuilder();

// Create a Type with features
Type t1 = builder.createWithName(Type.class, "t1");
Feature t1f1 = builder.createInWithName(Feature.class, t1, "t1Feature");
Type t2 = builder.createWithName(Type.class, "t2");
Feature t2f1 = builder.createInWithName(Feature.class, t2, "t2Feature");
Type t3 = builder.createWithName(Type.class, "t3");
Feature t3f1 = builder.createInWithName(Feature.class, t3, "t1Feature");

builder.setType(t1f1, t2);
builder.setType(t2f1, t3);

// Create a Feature Chain

Feature featureChain = builder.createFeatureChaining(t1f1, t2f1);

assertThat(featureChain.getFeatureTarget()).isEqualTo(t2f1);
assertThat(featureChain.getType()).contains(t3);

assertThat(featureChain.getFeature()).isEqualTo(List.of(t3f1));
}

}
19 changes: 19 additions & 0 deletions doc/content/modules/user-manual/pages/release-notes/2025.8.0.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,25 @@ Moreover, the tooling has been improved to:
- Fix an issue where model and diagrams referencing standard libraries elements might not correctly loaded.
- Fix an issue where model and diagrams referencing standard libraries elements might not correctly saved.

- Fix an issue where the type property of `Feature` that owns `FeatureChaining` was not correctly set.
The type of the last `FeatureChaining` is now added to the list of type of the owning feature.

For example in:

```
Type T1 {
feature t1Feature : T2;
}
Type T2 {
feature t2Feature : T3;
}
Type T3 {
feature t3Feature ;
}
```

The `FeatureChain` _t1Feature.t2Feature_ is now typed with _T3_.

== Improvements

== Dependency update
Expand Down
Loading