Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e115235
ST6RI-897 Moved name escaping/body processing to adapter postProcess.
seidewitz Jan 28, 2026
5e9edcd
ST6RI-897 Added "@generated NOT" tag to hand-coded additional overrides.
seidewitz Jan 29, 2026
88e7dd5
ST6RI-897 Re-tagged FeatureImpl.isOrdered as being generated.
seidewitz Jan 29, 2026
2e0a662
ST6RI-897 Moved redefinition of isComposite defaults to constructors.
seidewitz Jan 29, 2026
a327aa7
ST6RI-897 Moved overrides of isComposite into adapter postProcess.
seidewitz Jan 29, 2026
fdebe52
ST6RI-897 Moved redefinition of other defaults to constructors.
seidewitz Jan 29, 2026
2328589
ST6RI-897 Moved non-gen Feature.isEnd and getDirection code to adapters.
seidewitz Jan 29, 2026
b88e84c
ST6RI-897 Moved non-gen code for FlowUsage.isAbstract to adapter.
seidewitz Jan 29, 2026
158e32e
ST6RI-897 Removed non-generation of getSpecific and getRedefinedFeature.
seidewitz Jan 29, 2026
1e5763f
ST6RI-897 Implemented a setting delegate for Feature::isNonunique.
seidewitz Jan 30, 2026
0a8801c
ST6RI-897 Moved override of RenderingUsage.namingFeature to delegate.
seidewitz Jan 30, 2026
3410252
ST6RI-897 Moved the setting of elementIds to ElementAdapter.
seidewitz Feb 1, 2026
a916c5f
ST6RI-897 Moved the InvocationExpression operand mechanism to adapter.
seidewitz Feb 1, 2026
259ca00
ST6RI-897 Deleted and regenerated Java EMF metamodel classes.
seidewitz Feb 3, 2026
976621c
ST6RI-897 Added checks for validations previously "auto satisfied."
seidewitz Feb 3, 2026
bf8a4e9
ST6RI-897 Updated relations tests to not use EndFeature/ParamMembership.
seidewitz Feb 3, 2026
69f5834
ST6RI-897 Avoided possible NPE in ConnectorUtil.addConnectorEndTo.
seidewitz Jan 31, 2026
7e8ef0d
ST6RI-897 Handled TODO in check ofg validateDefVariationOwnedFeatureMem.
seidewitz Feb 3, 2026
6102846
ST6RI-897 Added @Deprecated tag to InvocationExpression.getOperand.
seidewitz Feb 4, 2026
f4d49e1
ST6RI-897 Updated custom importer so elementId is not used as an EMF ID.
seidewitz Feb 6, 2026
dd984ec
ST6RI-897 Fixed validation errors in sequence realization examples.
seidewitz Feb 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//*
XPECT_SETUP org.omg.kerml.xpect.tests.validation.KerMLValidationTest
ResourceSet {
ThisFile {}
File {from ="/library/Base.kerml"}
}
Workspace {
JavaProject {
SrcFolder {
ThisFile {}
File {from ="/library/Base.kerml"}
}
}
}
END_SETUP
*/
package Feature_nonunique_invalid {
classifier A {
feature x; // "unique" by default
}
classifier B specializes A {
// XPECT errors --> "Subsetting/redefining feature cannot be nonunique if subsetted/redefined feature is unique" at "x"
feature x1 nonunique subsets x;
}
classifier C specializes A {
// XPECT errors --> "Subsetting/redefining feature cannot be nonunique if subsetted/redefined feature is unique" at "x"
feature x2 nonunique redefines x;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
* SysML 2 Pilot Implementation
* Copyright (c) 2020-2021, 2024 Model Driven Solutions, Inc.
* Copyright (c) 2020-2021, 2024, 2026 Model Driven Solutions, Inc.
* Copyright (c) 2024 Budapest University of Technology and Economics
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -47,14 +47,6 @@ public class KerMLLinker extends LazyLinker {
@Inject
private OnChangeEvictingCache cache;

@Override
protected void clearReferences(EObject obj) {
super.clearReferences(obj);
if (obj instanceof Element) {
ElementUtil.clean((Element)obj);
}
}

@Override
protected void clearReference(EObject obj, EReference ref) {
if (
Expand All @@ -72,10 +64,10 @@ protected void clearReference(EObject obj, EReference ref) {
@Override
protected void doLinkModel(EObject model, IDiagnosticConsumer consumer) {
super.doLinkModel(model, consumer);
postProcessAllCrossReferences(model);
postProcessAll(model);
}

protected void postProcessAllCrossReferences(EObject model) {
protected void postProcessAll(EObject model) {
cache.execWithoutCacheClear(model.eResource(), new IUnitOfWork.Void<Resource>() {
@Override
public void process(Resource state) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*****************************************************************************
* SysML 2 Pilot Implementation
* Copyright (c) 2018 IncQuery Labs Ltd.
* Copyright (c) 2018-2025 Model Driven Solutions, Inc.
* Copyright (c) 2018-2026 Model Driven Solutions, Inc.
* Copyright (c) 2020 California Institute of Technology/Jet Propulsion Laboratory
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -103,6 +103,10 @@ import java.util.Collections
import java.util.HashMap
import java.util.Set
import java.util.Map
import org.omg.sysml.lang.sysml.EndFeatureMembership
import org.omg.sysml.lang.sysml.CollectExpression
import org.omg.sysml.lang.sysml.SelectExpression
import org.omg.sysml.lang.sysml.IndexExpression

/**
* This class contains custom validation rules.
Expand Down Expand Up @@ -160,6 +164,9 @@ class KerMLValidator extends AbstractKerMLValidator {

public static val INVALID_CLASSIFIER_MULTIPLICITY_DOMAIN = "validateClassifierMultiplicityDomain"
public static val INVALID_CLASSIFIER_MULTIPLICITY_DOMAIN_MSG = "Multiplicity must not have a featuring type"

public static val INVALID_END_FEATURE_MEMBERSHIP_IS_END = "validateEndFeatureMembershpIsEnd"
public static val INVALID_END_FEATURE_MEMBERSHIP_IS_END_MSG = "Must be an end feature"

// Note: validateFeatureHasType is not in the spec, but it is implied by semantic constraints on features.
public static val INVALID_FEATURE_HAS_TYPE = 'validateFeatureHasType_'
Expand Down Expand Up @@ -264,6 +271,8 @@ class KerMLValidator extends AbstractKerMLValidator {
public static val INVALID_BEHAVIOR_SPECIALIZATION = "validateBehaviorSpecialization"
public static val INVALID_BEHAVIOR_SPECIALIZATION_MSG = "Cannot specialize structure"

public static val INVALID_PARAMETER_MEMBERSHIP_DIRECTION = "validateParameterMembershipDirection"
public static val INVALID_PARAMETER_MEMBERSHIP_DIRECTION_MSG = "Must have direction '{direction}'"
public static val INVALID_PARAMETER_MEMBERSHIP_OWNING_TYPE = "validateParameterMembershipOwningType"
public static val INVALID_PARAMETER_MEMBERSHIP_OWNING_TYPE_MSG = "Parameter membership not allowed"

Expand Down Expand Up @@ -319,9 +328,23 @@ class KerMLValidator extends AbstractKerMLValidator {
public static val INVALID_OPERATOR_EXPRESSION_BRACKET_OPERATOR = "validateOperatorExpressionBracketOperator_"
public static val INVALID_OPERATOR_EXPRESSION_BRACKET_OPERATOR_MSG = "Use #(...) for indexing"

public static val INVALID_COLLECT_EXPRESSION_OPERATOR = "validateCollectExpressionOperator"
public static val INVALID_COLLECT_EXPRESSION_OPERATOR_MSG = "Operator must be 'collect'"

public static val INVALID_FEATURE_CHAIN_EXPRESSION_OPERATOR = "validateFeatureChainExpressionOperator"
public static val INVALID_FEATURE_CHAIN_EXPRESSION_OPERATOR_MSG = "Operator must be '.'"

public static val INVALID_INDEX_EXPRESSION_OPERATOR = "validateIndexExpressionOperator"
public static val INVALID_INDEX_EXPRESSION_OPERATOR_MSG = "Operator must be '#'"

public static val INVALID_SELECT_EXPRESSION_OPERATOR = "validateSelectExpressionOperator"
public static val INVALID_SELECT_EXPRESSION_OPERATOR_MSG = "Operator must be 'select'"

public static val INVALID_FLOW_ITEM_FEATURE = "validateFlowItemFeature"
public static val INVALID_FLOW_ITEM_FEATURE_MSG = "Only one item feature is allowed"

public static val INVALID_FLOW_END_IS_END = "validateFlowEndIsEnd"
public static val INVALID_FLOW_END_IS_END_MSG = "Must be an end feature"
public static val INVALID_FLOW_END_OWNING_TYPE = "validateFlowEndOwningType"
public static val INVALID_FLOW_END_OWNING_TYPE_MSG = "Flow end not allowed"
public static val INVALID_FLOW_END_NESTED_FEATURE = "validateFlowEndNestedFeature"
Expand Down Expand Up @@ -555,10 +578,14 @@ class KerMLValidator extends AbstractKerMLValidator {
}
}

// @Check
// def checkEndFeatureMembership(EndFeatureMembership m) {
// // validateEndFeatureMembershipIsEnd is automatically satisfied
// }
@Check
def checkEndFeatureMembership(EndFeatureMembership m) {
// validateEndFeatureMembershipIsEnd
var ownedMemberFeature = m.ownedMemberFeature
if (ownedMemberFeature !== null && !ownedMemberFeature.isEnd) {
error(INVALID_END_FEATURE_MEMBERSHIP_IS_END_MSG, ownedMemberFeature, null, INVALID_END_FEATURE_MEMBERSHIP_IS_END)
}
}

@Check
def checkFeature(Feature f){
Expand Down Expand Up @@ -1026,9 +1053,12 @@ class KerMLValidator extends AbstractKerMLValidator {
ExpressionUtil.isConstructorResult(owningType))) {
error(INVALID_PARAMETER_MEMBERSHIP_OWNING_TYPE_MSG, m, SysMLPackage.eINSTANCE.parameterMembership_OwnedMemberParameter, INVALID_PARAMETER_MEMBERSHIP_OWNING_TYPE)
}

// validateParameterMembershipParameterHasDirection is automatically satisfied
}
// validateParameterMembershipParameterDirection
var ownedMemberParameter = m.ownedMemberParameter
if (ownedMemberParameter !== null && ownedMemberParameter.direction != m.parameterDirection) {
error(INVALID_PARAMETER_MEMBERSHIP_DIRECTION_MSG.replace("{direction}", m.parameterDirection.toString.toLowerCase), ownedMemberParameter, null, INVALID_PARAMETER_MEMBERSHIP_DIRECTION)
}
}

@Check
Expand Down Expand Up @@ -1074,8 +1104,6 @@ class KerMLValidator extends AbstractKerMLValidator {
if (!(owningType instanceof Function || owningType instanceof Expression)) {
error(INVALID_RETURN_PARAMETER_MEMBERSHIP_OWNING_TYPE_MSG, m, SysMLPackage.eINSTANCE.parameterMembership_OwnedMemberParameter, INVALID_RETURN_PARAMETER_MEMBERSHIP_OWNING_TYPE)
}

// validateReturnParameterMembershipParameterHasDirectionOut is automatically satisfied
}

@Check
Expand All @@ -1085,19 +1113,15 @@ class KerMLValidator extends AbstractKerMLValidator {
if (!(owningType instanceof Function || owningType instanceof Expression)) {
error(INVALID_RESULT_EXPRESSION_MEMBERSHIP_OWNING_TYPE_MSG, m, SysMLPackage.eINSTANCE.parameterMembership_OwnedMemberParameter, INVALID_RESULT_EXPRESSION_MEMBERSHIP_OWNING_TYPE)
}

// validateReturnParameterMembershipParameterHasDirectionOut is automatically satisfied
}

// @Check
// def checkReturnParameterMembership(ReturnParameterMembership m) {
// // validateReturnParameterMembershipParameterHasDirection is automatically satisfied
// }

// @Check
// def checkCollectExpression(CollectExpression e) {
// // validateCollectExpressionOperator is automatically satisfied
// }
@Check
def checkCollectExpression(CollectExpression e) {
// validateCollectExpressionOperator
if (e.operator != "collect") {
error(INVALID_COLLECT_EXPRESSION_OPERATOR_MSG, e, null, INVALID_COLLECT_EXPRESSION_OPERATOR);
}
}

@Check
def checkFeatureChainExpression(FeatureChainExpression e) {
Expand All @@ -1112,7 +1136,10 @@ class KerMLValidator extends AbstractKerMLValidator {
error(INVALID_FEATURE_CHAIN_EXPRESSION_FEATURE_CONFORMANCE_MSG, e.ownedMembership.get(1), SysMLPackage.eINSTANCE.membership_MemberElement, INVALID_FEATURE_CHAIN_EXPRESSION_FEATURE_CONFORMANCE)
}

// validateFeatureChainExpressionOperator is automatically satisfied
// validateFeatureChainExpressionOperator
if (e.operator != ".") {
error(INVALID_FEATURE_CHAIN_EXPRESSION_OPERATOR_MSG, e, null, INVALID_FEATURE_CHAIN_EXPRESSION_OPERATOR);
}
}

@Check
Expand Down Expand Up @@ -1235,15 +1262,21 @@ class KerMLValidator extends AbstractKerMLValidator {
}
}

// @Check
// def checkSelectExpression(SelectExpression e) {
// // validateSelectExpressionOperator is automatically satisfied
// }

// @Check
// def checkIndexExpression(IndexExpression e) {
// // validateIndexExpressionOperator is automatically satisfied
// }
@Check
def checkSelectExpression(SelectExpression e) {
// validateSelectExpressionOperator
if (e.operator != "select") {
error(INVALID_SELECT_EXPRESSION_OPERATOR_MSG, e, null, INVALID_SELECT_EXPRESSION_OPERATOR);
}
}

@Check
def checkIndexExpression(IndexExpression e) {
// validateIndexExpressionOperator
if (e.operator != "#") {
error(INVALID_INDEX_EXPRESSION_OPERATOR_MSG, e, null, INVALID_INDEX_EXPRESSION_OPERATOR);
}
}

@Check
def checkFlow(Flow flow) {
Expand All @@ -1254,7 +1287,10 @@ class KerMLValidator extends AbstractKerMLValidator {

@Check
def checkFlowEnd(FlowEnd flowEnd) {
// validateFlowEndIsEnd is automatically satisfied
// validateFlowEndIsEnd
if (!flowEnd.isEnd) {
error(INVALID_FLOW_END_IS_END_MSG, flowEnd, null, INVALID_FLOW_END_IS_END)
}

// validateFlowEndNestedFeature
if (flowEnd.ownedFeature.size != 1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ protected Expression checkFilterExpression(SysMLInteractive instance, String tex
assertFalse("'" + text + "': No filter conditions", filterConditions.isEmpty());
Expression filterCondition = filterConditions.get(0);
assertTrue("'" + text + "': Not operator expression", filterCondition instanceof OperatorExpression);
List<Expression> operands = ((OperatorExpression)filterCondition).getOperand();
List<Expression> operands = ((OperatorExpression)filterCondition).getArgument();
assertFalse("'" + text + "': No operands", operands.isEmpty());
return operands.get(0);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* SysML 2 Pilot Implementation
* Copyright (C) 2024,2025 Model Driven Solutions, Inc.
* Copyright (C) 2024-2026 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -132,7 +132,8 @@ public void checkSuccessionFlowUsageSpecialization() {

public static void addEndTo(Type type) {
var end = SysMLFactory.eINSTANCE.createFeature();
var endMembership = SysMLFactory.eINSTANCE.createEndFeatureMembership();
end.setIsEnd(true);
var endMembership = SysMLFactory.eINSTANCE.createFeatureMembership();
endMembership.setOwnedMemberFeature(end);
type.getOwnedRelationship().add(endMembership);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* SysML 2 Pilot Implementation
* Copyright (C) 2024, 2025 Model Driven Solutions, Inc.
* Copyright (C) 2024-2026 Model Driven Solutions, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand All @@ -27,7 +27,6 @@
import org.junit.Ignore;
import org.junit.Test;
import org.omg.sysml.lang.sysml.FeatureDirectionKind;
import org.omg.sysml.lang.sysml.ParameterMembership;
import org.omg.sysml.lang.sysml.StateSubactionKind;
import org.omg.sysml.lang.sysml.SysMLFactory;
import org.omg.sysml.util.ElementUtil;
Expand Down Expand Up @@ -104,10 +103,7 @@ public void checkAssignmentActionUsageAccessedFeatureRedefinition() {

var targetParam = SysMLFactory.eINSTANCE.createFeature();
targetParam.setDirection(FeatureDirectionKind.IN);

ParameterMembership parameterMembership = SysMLFactory.eINSTANCE.createParameterMembership();
assignment.getOwnedRelationship().add(parameterMembership);
parameterMembership.setOwnedMemberParameter(targetParam);
TypeUtil.addOwnedFeatureTo(assignment, targetParam);

var firstOfTarget = SysMLFactory.eINSTANCE.createFeature();
TypeUtil.addOwnedFeatureTo(targetParam, firstOfTarget);
Expand Down Expand Up @@ -136,10 +132,7 @@ public void checkAssignmentActionUsageReferentRedefinition() {

var targetParam = SysMLFactory.eINSTANCE.createFeature();
targetParam.setDirection(FeatureDirectionKind.IN);

ParameterMembership parameterMembership = SysMLFactory.eINSTANCE.createParameterMembership();
assignment.getOwnedRelationship().add(parameterMembership);
parameterMembership.setOwnedMemberParameter(targetParam);
TypeUtil.addOwnedFeatureTo(assignment, targetParam);

var firstOfTarget = SysMLFactory.eINSTANCE.createFeature();
TypeUtil.addOwnedFeatureTo(targetParam, firstOfTarget);
Expand All @@ -163,10 +156,7 @@ public void checkAssignmentActionUsageStartingAtRedefinition() {

var targetParam = SysMLFactory.eINSTANCE.createFeature();
targetParam.setDirection(FeatureDirectionKind.IN);

ParameterMembership parameterMembership = SysMLFactory.eINSTANCE.createParameterMembership();
assignment.getOwnedRelationship().add(parameterMembership);
parameterMembership.setOwnedMemberParameter(targetParam);
TypeUtil.addOwnedFeatureTo(assignment, targetParam);

var firstOfTarget = SysMLFactory.eINSTANCE.createFeature();
TypeUtil.addOwnedFeatureTo(targetParam, firstOfTarget);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private class PCFeatureChainExpression extends PC {
private final FeatureChainExpression fce;

private Expression getTargetExp() {
List<Expression> ops = fce.getOperand();
List<Expression> ops = fce.getArgument();
if (ops.isEmpty()) {
return null;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private static boolean isTarget(Feature f) {
}

private Element next(FeatureChainExpression fce, boolean first) {
List<Expression> ops = fce.getOperand();
List<Expression> ops = fce.getArgument();
int size = ops.size();
if (size == 0) return null;
Expression ex = ops.get(0);
Expand Down
Loading