From 9108f2065d1238f22824e083f25f788223bc739d Mon Sep 17 00:00:00 2001 From: Axel RICHARD Date: Mon, 27 Jul 2026 16:16:41 +0200 Subject: [PATCH] ST6RI-951 Fix NullPointerException in FeatureAdapter#getTypes FeatureAdapter#getTypes(...) can throw a NullPointerException when deriving the type of a Feature whose typingFeatures() result contains a null entry. This can happen for a syntactically valid SysML model during intermediate model construction, import, or partial linking, when a FeatureChaining relationship exists but its chainingFeature reference has not been resolved yet. The fix is small and defensive: skip null entries returned by feature.typingFeatures() before recursively calling FeatureUtil.getTypesOf(...). Signed-off-by: Axel RICHARD --- .../org/omg/sysml/adapter/FeatureAdapter.java | 5 +- .../omg/sysml/logic/FeatureAdapterTest.java | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/FeatureAdapterTest.java diff --git a/org.omg.sysml.logic/src/main/java/org/omg/sysml/adapter/FeatureAdapter.java b/org.omg.sysml.logic/src/main/java/org/omg/sysml/adapter/FeatureAdapter.java index d24992bd0d..7739361d39 100644 --- a/org.omg.sysml.logic/src/main/java/org/omg/sysml/adapter/FeatureAdapter.java +++ b/org.omg.sysml.logic/src/main/java/org/omg/sysml/adapter/FeatureAdapter.java @@ -1,7 +1,8 @@ /******************************************************************************* * SysML 2 Pilot Implementation * Copyright (c) 2021-2026 Model Driven Solutions, Inc. - * + * Copyright (c) 2026 Obeo + * * This program is free software: you can redistribute it and/or modify * it under the terms of the Eclipse Public License as published by * the Eclipse Foundation, version 2 of the License. @@ -558,7 +559,7 @@ public void getTypes(List types, Set visitedFeatures) { computeImplicitGeneralTypes(); getFeatureTypes(types, visitedFeatures); for (Feature typingFeature : feature.typingFeatures()) { - if (!visitedFeatures.contains(typingFeature)) { + if (typingFeature != null && !visitedFeatures.contains(typingFeature)) { FeatureUtil.getTypesOf(typingFeature, types, visitedFeatures); } } diff --git a/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/FeatureAdapterTest.java b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/FeatureAdapterTest.java new file mode 100644 index 0000000000..b80e2b8b40 --- /dev/null +++ b/org.omg.sysml.logic/src/test/java/org/omg/sysml/logic/FeatureAdapterTest.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * SysML 2 Pilot Implementation + * Copyright (c) 2026 Obeo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Eclipse Public License as published by + * the Eclipse Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Eclipse Public License for more details. + * + * You should have received a copy of theEclipse Public License + * along with this program. If not, see . + * + * @license EPL-2.0 + * + *******************************************************************************/ + +package org.omg.sysml.logic; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.omg.sysml.lang.sysml.Feature; +import org.omg.sysml.lang.sysml.FeatureChaining; +import org.omg.sysml.lang.sysml.SysMLFactory; +import org.omg.sysml.lang.sysml.SysMLPackage; + +/** + * Tests feature derived-property computations implemented by the logic adapters. + */ +public class FeatureAdapterTest { + + /** + * A partially linked feature chain can contribute a null entry to + * typingFeatures(). Type derivation must ignore that unresolved chaining + * target instead of recursing into it. + */ + @Test + public void typeDerivationIgnoresUnresolvedChainingFeature() { + SysMLLogicStandaloneSetup.doSetup(); + SysMLPackage.eINSTANCE.eClass(); + + Feature feature = SysMLFactory.eINSTANCE.createFeature(); + FeatureChaining unresolvedChaining = SysMLFactory.eINSTANCE.createFeatureChaining(); + feature.getOwnedRelationship().add(unresolvedChaining); + + assertNull(feature.typingFeatures().get(0)); + assertTrue(feature.getType().isEmpty()); + } +}