Skip to content

Commit fd82aac

Browse files
committed
ST6RI-884 Implemented ControlFunctions collect and select.
1 parent adb4ff9 commit fd82aac

7 files changed

Lines changed: 207 additions & 18 deletions

File tree

org.omg.sysml.execution/src/org/omg/sysml/execution/expressions/ExpressionEvaluator.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************************
22
* SysML 2 Pilot Implementation
3-
* Copyright (c) 2022-2024 Model Driven Solutions, Inc.
3+
* Copyright (c) 2022-2025 Model Driven Solutions, Inc.
44
*
55
* This program is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU Lesser General Public License as published by
@@ -36,7 +36,6 @@
3636
import org.omg.sysml.lang.sysml.SysMLFactory;
3737
import org.omg.sysml.lang.sysml.Type;
3838
import org.omg.sysml.util.ElementUtil;
39-
import org.omg.sysml.util.ExpressionUtil;
4039
import org.omg.sysml.util.FeatureUtil;
4140
import org.omg.sysml.util.TypeUtil;
4241

@@ -57,16 +56,7 @@ public EList<Element> evaluateInvocation(InvocationExpression expression, Elemen
5756
return libraryFunction.invoke(expression, target, this);
5857
} else {
5958
Type type = expression.instantiatedType();
60-
Expression resultExpression = null;
61-
if (type != null) {
62-
resultExpression = ExpressionUtil.getResultExpressionOf(type);
63-
if (resultExpression == null) {
64-
Feature resultParameter = TypeUtil.getResultParameterOf(type);
65-
if (resultParameter != null) {
66-
resultExpression = FeatureUtil.getValueExpressionFor(resultParameter);
67-
}
68-
}
69-
}
59+
Expression resultExpression = EvaluationUtil.getResultExpressionFor(type);
7060
if (resultExpression == null) {
7161
return EvaluationUtil.singletonList(expression);
7262
} else {

org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelExpressionEvaluator.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public EList<Element> evaluate(Expression expression, Element target) {
7878
} else if (expression instanceof ConstructorExpression) {
7979
return evaluateConstructor((ConstructorExpression)expression, target);
8080
} else {
81-
return new BasicEList<>();
81+
return evaluateExpression(expression, target);
8282
}
8383
}
8484

@@ -117,6 +117,18 @@ public EList<Element> evaluateConstructor(ConstructorExpression expression, Elem
117117
return resultParameter == null? null: EvaluationUtil.singletonList(resultParameter);
118118
}
119119

120+
public EList<Element> evaluateExpression(Expression expression, Element target, Element... arguments) {
121+
Expression resultExpression = EvaluationUtil.getResultExpressionFor(expression);
122+
if (resultExpression == null) {
123+
return EvaluationUtil.singletonList(expression);
124+
} else {
125+
Feature targetFeature = EvaluationUtil.getTargetFeatureFor(target);
126+
Expression invocation = EvaluationUtil.createInvocationOf(expression, arguments);
127+
EList<Element> results = evaluate(resultExpression, FeatureUtil.chainFeatures(targetFeature, invocation));
128+
return results == null? EvaluationUtil.singletonList(resultExpression): results;
129+
}
130+
}
131+
120132
public EList<Element> evaluateFeature(Feature feature, Type type) {
121133
if (type != null && TypeUtil.specializes(feature, ExpressionUtil.getSelfReferenceFeature(feature))) {
122134
// Evaluate "self" feature. (Note: Must be checked before test for feature chain because "self" has chaining features.)

org.omg.sysml/src/org/omg/sysml/expressions/ModelLevelLibraryFunctionFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ protected void initializeFunctionMap() {
7676
put(new ConditionalOrFunction());
7777
put(new ConditionalImpliesFunction());
7878
put(new NullCoalescingFunction());
79+
80+
put(new CollectFunction());
81+
put(new SelectFunction());
7982
}
8083

8184
protected void put(LibraryFunction functionImpl) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*******************************************************************************
2+
* SysML 2 Pilot Implementation
3+
* Copyright (c) 2025 Model Driven Solutions, Inc.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
* @license LGPL-3.0-or-later <http://spdx.org/licenses/LGPL-3.0-or-later>
19+
*
20+
*******************************************************************************/
21+
package org.omg.sysml.expressions.functions;
22+
23+
import java.util.function.BiFunction;
24+
25+
import org.eclipse.emf.common.util.EList;
26+
import org.omg.sysml.expressions.ModelLevelExpressionEvaluator;
27+
import org.omg.sysml.lang.sysml.Element;
28+
import org.omg.sysml.lang.sysml.InvocationExpression;
29+
30+
public class CollectFunction extends ControlFunction {
31+
32+
@Override
33+
public String getOperatorName() {
34+
return "collect";
35+
}
36+
37+
@Override
38+
public EList<Element> invoke(InvocationExpression invocation, Element target,
39+
ModelLevelExpressionEvaluator evaluator) {
40+
return collectSelected(invocation, target, evaluator, new BiFunction<>() {
41+
@Override
42+
public EList<Element> apply(Element value, EList<Element> exprValue) {
43+
return exprValue;
44+
}
45+
});
46+
}
47+
48+
}

org.omg.sysml/src/org/omg/sysml/expressions/functions/ControlFunction.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************************
22
* SysML 2 Pilot Implementation
3-
* Copyright (c) 2021 Model Driven Solutions, Inc.
3+
* Copyright (c) 2021, 2025 Model Driven Solutions, Inc.
44
*
55
* This program is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU Lesser General Public License as published by
@@ -21,11 +21,43 @@
2121

2222
package org.omg.sysml.expressions.functions;
2323

24+
import java.util.function.BiFunction;
25+
26+
import org.eclipse.emf.common.util.BasicEList;
27+
import org.eclipse.emf.common.util.EList;
28+
import org.omg.sysml.expressions.ModelLevelExpressionEvaluator;
29+
import org.omg.sysml.expressions.util.EvaluationUtil;
30+
import org.omg.sysml.lang.sysml.Element;
31+
import org.omg.sysml.lang.sysml.Expression;
32+
import org.omg.sysml.lang.sysml.InvocationExpression;
33+
2434
public abstract class ControlFunction implements LibraryFunction {
2535

2636
@Override
2737
public String getPackageName() {
2838
return "ControlFunctions";
2939
}
3040

41+
protected EList<Element> collectSelected(InvocationExpression invocation, Element target,
42+
ModelLevelExpressionEvaluator evaluator,
43+
BiFunction<Element, EList<Element>, EList<Element>> select) {
44+
EList<Element> list = evaluator.evaluateArgument(invocation, 0, target);
45+
Element expr = evaluator.argumentValue(invocation, 1, target);
46+
if (list == null || !(expr instanceof Expression)) {
47+
return EvaluationUtil.singletonList(invocation);
48+
} else {
49+
EList<Element> result = new BasicEList<>();
50+
for (Element value: list) {
51+
if (value == null) {
52+
return EvaluationUtil.singletonList(invocation);
53+
} else {
54+
EList<Element> exprValue = evaluator.evaluateExpression((Expression)expr, target, value);
55+
if (exprValue != null) {
56+
result.addAll(select.apply(value, exprValue));
57+
}
58+
}
59+
}
60+
return result;
61+
}
62+
}
3163
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*******************************************************************************
2+
* SysML 2 Pilot Implementation
3+
* Copyright (c) 2025 Model Driven Solutions, Inc.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*
18+
* @license LGPL-3.0-or-later <http://spdx.org/licenses/LGPL-3.0-or-later>
19+
*
20+
*******************************************************************************/
21+
package org.omg.sysml.expressions.functions;
22+
23+
import java.util.function.BiFunction;
24+
25+
import org.eclipse.emf.common.util.EList;
26+
import org.omg.sysml.expressions.ModelLevelExpressionEvaluator;
27+
import org.omg.sysml.expressions.util.EvaluationUtil;
28+
import org.omg.sysml.lang.sysml.Element;
29+
import org.omg.sysml.lang.sysml.InvocationExpression;
30+
31+
public class SelectFunction extends ControlFunction {
32+
33+
@Override
34+
public String getOperatorName() {
35+
return "select";
36+
}
37+
38+
@Override
39+
public EList<Element> invoke(InvocationExpression invocation, Element target,
40+
ModelLevelExpressionEvaluator evaluator) {
41+
return collectSelected(invocation, target, evaluator, new BiFunction<>() {
42+
@Override
43+
public EList<Element> apply(Element value, EList<Element> exprValue) {
44+
return exprValue != null && exprValue.size() == 1 && Boolean.TRUE.equals(EvaluationUtil.valueOf(exprValue.get(0)))?
45+
EvaluationUtil.singletonList(value):
46+
EvaluationUtil.nullList();
47+
}
48+
});
49+
}
50+
51+
}

org.omg.sysml/src/org/omg/sysml/expressions/util/EvaluationUtil.java

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*******************************************************************************
22
* SysML 2 Pilot Implementation
3-
* Copyright (c) 2022 Model Driven Solutions, Inc.
3+
* Copyright (c) 2022, 2025 Model Driven Solutions, Inc.
44
*
55
* This program is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU Lesser General Public License as published by
@@ -31,8 +31,10 @@
3131
import org.omg.sysml.lang.sysml.Element;
3232
import org.omg.sysml.lang.sysml.Expression;
3333
import org.omg.sysml.lang.sysml.Feature;
34+
import org.omg.sysml.lang.sysml.FeatureDirectionKind;
3435
import org.omg.sysml.lang.sysml.FeatureReferenceExpression;
3536
import org.omg.sysml.lang.sysml.FeatureTyping;
37+
import org.omg.sysml.lang.sysml.FeatureValue;
3638
import org.omg.sysml.lang.sysml.InvocationExpression;
3739
import org.omg.sysml.lang.sysml.LiteralBoolean;
3840
import org.omg.sysml.lang.sysml.LiteralExpression;
@@ -41,6 +43,7 @@
4143
import org.omg.sysml.lang.sysml.LiteralRational;
4244
import org.omg.sysml.lang.sysml.LiteralString;
4345
import org.omg.sysml.lang.sysml.MetadataFeature;
46+
import org.omg.sysml.lang.sysml.Redefinition;
4447
import org.omg.sysml.lang.sysml.SysMLFactory;
4548
import org.omg.sysml.lang.sysml.SysMLPackage;
4649
import org.omg.sysml.lang.sysml.Type;
@@ -52,8 +55,6 @@
5255
import org.omg.sysml.util.NamespaceUtil;
5356
import org.omg.sysml.util.TypeUtil;
5457

55-
import com.google.common.base.Predicates;
56-
5758
public class EvaluationUtil {
5859

5960
public static Feature getAnnotatedElementFeature(MetadataFeature metadata) {
@@ -145,7 +146,7 @@ public static EList<Element> results(Object object) {
145146
if (object instanceof List) {
146147
((List<?>)object).stream().
147148
map(EvaluationUtil::elementFor).
148-
filter(Predicates.notNull()).
149+
filter(e->e != null).
149150
forEachOrdered(results::add);
150151
} else if (object != null) {
151152
Element element = elementFor(object);
@@ -258,6 +259,20 @@ public static Feature getTypeFeatureFor(Feature feature, Type type) {
258259
filter(f->FeatureUtil.getAllRedefinedFeaturesOf(f).contains(feature)).
259260
findFirst().orElse(null);
260261
}
262+
263+
public static Expression getResultExpressionFor(Type type) {
264+
Expression resultExpression = null;
265+
if (type != null) {
266+
resultExpression = ExpressionUtil.getResultExpressionOf(type);
267+
if (resultExpression == null) {
268+
Feature resultParameter = TypeUtil.getResultParameterOf(type);
269+
if (resultParameter != null) {
270+
resultExpression = FeatureUtil.getValueExpressionFor(resultParameter);
271+
}
272+
}
273+
}
274+
return resultExpression;
275+
}
261276

262277
public static boolean isMetaclassFeature(Element element) {
263278
return getMetaclassReferenceOf(element) != null;
@@ -299,5 +314,43 @@ public static boolean hasType(Element context, Element element, Type type) {
299314
public static boolean isMetatype(Element element, Type targetType) {
300315
return TypeUtil.specializes(ElementUtil.getMetaclassOf(element), targetType);
301316
}
317+
318+
public static void instantiateArguments(Feature target, List<Feature> parameters, Element[] arguments) {
319+
for (int i = 0; i < arguments.length && i < parameters.size(); i++) {
320+
Element argument = arguments[i];
321+
Feature parameter = parameters.get(i);
322+
if (argument instanceof Feature) {
323+
Feature actual = SysMLFactory.eINSTANCE.createFeature();
324+
actual.setDirection(FeatureDirectionKind.IN);
325+
TypeUtil.addOwnedFeatureTo(target, actual);
326+
327+
Expression valueExpr;
328+
if (argument instanceof Expression) {
329+
valueExpr = (Expression)argument;
330+
} else {
331+
valueExpr = SysMLFactory.eINSTANCE.createFeatureReferenceExpression();
332+
NamespaceUtil.addMemberTo(valueExpr, argument);
333+
}
334+
335+
FeatureValue featureValue = SysMLFactory.eINSTANCE.createFeatureValue();
336+
featureValue.setValue(valueExpr);
337+
actual.getOwnedRelationship().add(featureValue);
338+
339+
Redefinition redefinition = SysMLFactory.eINSTANCE.createRedefinition();
340+
redefinition.setRedefinedFeature(parameter);
341+
redefinition.setRedefiningFeature(actual);
342+
actual.getOwnedRelationship().add(redefinition);
343+
}
344+
}
345+
}
346+
347+
public static Expression createInvocationOf(Expression expression, Element... arguments) {
348+
Expression invocation = SysMLFactory.eINSTANCE.createExpression();
349+
FeatureUtil.addSubsettingTo(invocation).setSubsettedFeature(expression);
350+
351+
List<Feature> parameters = TypeUtil.getAllParametersOf(expression);
352+
instantiateArguments(invocation, parameters, arguments);
353+
return invocation;
354+
}
302355

303356
}

0 commit comments

Comments
 (0)