Skip to content
Open
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
5 changes: 5 additions & 0 deletions org.omg.sysml.xpect.tests/library.systems/Flows.sysml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ standard library package Flows {

ref payload :>> MessageAction::payload, Transfer::payload;

end occurrence source: Occurrence :>> Transfer::source;
end occurrence target: Occurrence :>> Transfer::target;

private ref action thisConnection = self;

in event occurrence sourceEvent [1] default thisConnection.start {
Expand Down Expand Up @@ -101,6 +104,8 @@ standard library package Flows {
/*
* messages is the base feature of all FlowUsages.
*/
end occurrence source: Occurrence :>> Message::source, transfers::source;
end occurrence target: Occurrence :>> Message::target, transfers::target;
}

abstract flow flows: Flow[0..*] nonunique :> messages, flowTransfers {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//*
XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
ResourceSet {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.systems/Items.sysml"}
File {from ="/library.systems/Parts.sysml"}
File {from ="/library.systems/Ports.sysml"}
File {from ="/library.systems/Connections.sysml"}
}
Workspace {
JavaProject {
SrcFolder {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.systems/Items.sysml"}
File {from ="/library.systems/Parts.sysml"}
File {from ="/library.systems/Ports.sysml"}
File {from ="/library.systems/Connections.sysml"}
}
}
}
END_SETUP
*/
package ConnectionUsage_End_Invalid {
// XPECT errors --> "A connection definition end must be a usage." at "abstract connection def B :> Links::BinaryLink;"
abstract connection def B :> Links::BinaryLink;
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
ResourceSet {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.kernel/Performances.kerml"}
Expand All @@ -17,6 +18,7 @@ XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
SrcFolder {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.kernel/Performances.kerml"}
Expand All @@ -30,7 +32,7 @@ XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
}
END_SETUP
*/
package P {
package ConnectionUsage_Invalid {
part def A;
part def B;
part def C;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//*
XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
ResourceSet {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.systems/Items.sysml"}
File {from ="/library.systems/Parts.sysml"}
File {from ="/library.systems/Ports.sysml"}
File {from ="/library.systems/Flows.sysml"}
}
Workspace {
JavaProject {
SrcFolder {
ThisFile {}
File {from ="/library.kernel/Base.kerml"}
File {from ="/library.kernel/Links.kerml"}
File {from ="/library.kernel/Occurrences.kerml"}
File {from ="/library.kernel/Objects.kerml"}
File {from ="/library.systems/Items.sysml"}
File {from ="/library.systems/Parts.sysml"}
File {from ="/library.systems/Ports.sysml"}
File {from ="/library.systems/Flows.sysml"}
}
}
}
END_SETUP
*/
package Flow_End_Invalid {
// XPECT errors --> "A flow definition end must be a usage." at "abstract flow def B :> Links::BinaryLink;"
abstract flow def B :> Links::BinaryLink;
}

Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ XPECT_SETUP org.omg.sysml.xpect.tests.validation.invalid.SysMLTests
}
END_SETUP
*/
package P {
package FlowUsage_Invalid {
part def A;

abstract flow def F;
Expand All @@ -49,11 +49,11 @@ package P {
flow def I :> H {
end a;
end b;
// XPECT errors --> "A flow connection definition can have at most two ends." at "end c;"
// XPECT errors --> "A flow definition can have at most two ends." at "end c;"
end c;
}

// XPECT errors --> "A flow connection definition can have at most two ends." at "flow def J :> I;"
// XPECT errors --> "A flow definition can have at most two ends." at "flow def J :> I;"
flow def J :> I;

part apart : A {
Expand All @@ -63,14 +63,14 @@ package P {
message : F from b to c;
message : F, G from b to c;

// XPECT errors --> "A flow connection must be typed by flow connection definitions." at "message :A from b to c;"
// XPECT errors --> "A flow usage must be typed by flow definitions." at "message :A from b to c;"
//* XPECT warnings ---
"Duplicate of inherited member name 'self' from Action, Part" at "message :A from b to c;"
"Duplicate of inherited member name 'start' from Action, Part" at "message :A from b to c;"
"Duplicate of inherited member name 'done' from Action, Part" at "message :A from b to c;"
--- */
message :A from b to c;
// XPECT errors --> "A flow connection must be typed by flow connection definitions." at "message :apart from b to c;"
// XPECT errors --> "A flow usage must be typed by flow definitions." at "message :apart from b to c;"
//* XPECT warnings ---
"Duplicate of inherited member name 'self' from Action, Part" at "message :apart from b to c;"
"Duplicate of inherited member name 'start' from Action, Part" at "message :apart from b to c;"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ import org.omg.sysml.util.FeatureUtil
import org.omg.sysml.util.UsageUtil
import org.omg.sysml.lang.sysml.MetadataFeature
import org.omg.sysml.util.TypeUtil
import org.omg.sysml.lang.sysml.ConnectionDefinition

/**
* This class contains custom validation rules.
Expand Down Expand Up @@ -234,14 +235,19 @@ class SysMLValidator extends KerMLValidator {
public static val INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE = "validatePortUsageNestedUsagesNotComposite"
public static val INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE_MSG = "Nested usages in a port usage (other than ports) must be referential."

public static val INVALID_CONNECTION_DEFINITION_ENDS_ARE_USAGES = "validateConnectionDefinitionEndsAreUsages_"
public static val INVALID_CONNECTION_DEFINITION_ENDS_ARE_USAGES_MSG = "A connection definition end must be a usage."

public static val INVALID_CONNECTION_USAGE_TYPE = "validateConnectionUsageType_"
public static val INVALID_CONNECTION_USAGE_TYPE_MSG = "A connection must be typed by connection definitions."

public static val INVALID_FLOW_DEFINITION_ENDS_ARE_USAGES = "validateFlowDefinitionEndsAreUsages_"
public static val INVALID_FLOW_DEFINITION_ENDS_ARE_USAGES_MSG = "A flow definition end must be a usage."
public static val INVALID_FLOW_DEFINITION_END = "validateFlowDefinitionConnectionEnds"
public static val INVALID_FLOW_DEFINITION_END_MSG = "A flow connection definition can have at most two ends."
public static val INVALID_FLOW_DEFINITION_END_MSG = "A flow definition can have at most two ends."

public static val INVALID_FLOW_USAGE_TYPE = "validateFlowUsageType_"
public static val INVALID_FLOW_USAGE_TYPE_MSG = "A flow connection must be typed by flow connection definitions."
public static val INVALID_FLOW_USAGE_TYPE_MSG = "A flow usage must be typed by flow definitions."

public static val INVALID_INTERFACE_DEFINITION_END = "validateInterfaceDefinitionEnd_"
public static val INVALID_INTERFACE_DEFINITION_END_MSG = "An interface definition end must be a port."
Expand Down Expand Up @@ -700,6 +706,12 @@ class SysMLValidator extends KerMLValidator {
val usages = usg.nestedUsage.filter[u | !(u instanceof PortUsage)]
checkAllNotComposite(usages, INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE_MSG, INVALID_PORT_USAGE_NESTED_USAGES_NOT_COMPOSITE)
}

@Check
def checkConnectionDefinition(ConnectionDefinition cdef) {
// validateConnectionDefinitionEndsAreUsages_
checkEndsAreUsages(cdef, INVALID_CONNECTION_DEFINITION_ENDS_ARE_USAGES_MSG, INVALID_CONNECTION_DEFINITION_ENDS_ARE_USAGES)
}

@Check
def checkConnectionUsage(ConnectionUsage usg) {
Expand All @@ -710,8 +722,10 @@ class SysMLValidator extends KerMLValidator {

@Check
def checkFlowDefinition(FlowDefinition cdef) {
// validateConnectionDefinitionConnectionEnds
val ends = cdef.endFeature
// validateFlowDefinitionEndsAreUsages_
val ends = checkEndsAreUsages(cdef, INVALID_FLOW_DEFINITION_ENDS_ARE_USAGES_MSG, INVALID_FLOW_DEFINITION_ENDS_ARE_USAGES)

// validateFlowDefinitionEnds
if (ends.size > 2) {
val ownedEnds = cdef.ownedEndFeature
if (ownedEnds.size <= 2) {
Expand Down Expand Up @@ -957,7 +971,7 @@ class SysMLValidator extends KerMLValidator {
// validateStateDefinitionParallelSubactions is checked by checkTransitionUsage and checkSuccession

// validateStateDefinitionStateSubactionKind
checkStateSubactions(defn);
checkStateSubactions(defn,INVALID_STATE_DEFINITION_SUBACTION_KIND)
}

@Check
Expand All @@ -977,14 +991,7 @@ class SysMLValidator extends KerMLValidator {
// validateStateUsageParallelSubactions is checked by checkTransitionUsage and checkSuccession

// validateStateUsageStateSubactionKind
checkStateSubactions(usg)
}

protected def checkStateSubactions(Type type) {
val errorId = type instanceof Definition? INVALID_STATE_DEFINITION_SUBACTION_KIND: INVALID_STATE_USAGE_SUBACTION_KIND
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.ENTRY), INVALID_STATE_SUBACTION_KIND_ENTRY_MSG, errorId);
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.DO), INVALID_STATE_SUBACTION_KIND_DO_MSG, errorId);
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.EXIT), INVALID_STATE_SUBACTION_KIND_EXIT_MSG, errorId);
checkStateSubactions(usg, INVALID_STATE_USAGE_SUBACTION_KIND)
}

@Check
Expand Down Expand Up @@ -1365,6 +1372,28 @@ class SysMLValidator extends KerMLValidator {

/* Utility Methods */

protected def checkStateSubactions(Type type, String errorId) {
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.ENTRY), INVALID_STATE_SUBACTION_KIND_ENTRY_MSG, errorId);
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.DO), INVALID_STATE_SUBACTION_KIND_DO_MSG, errorId);
checkAtMostOneRelationship(type, UsageUtil.getStateSubactionMembershipsOf(type, StateSubactionKind.EXIT), INVALID_STATE_SUBACTION_KIND_EXIT_MSG, errorId);
}

protected def checkEndsAreUsages(Type type, String msg, String errorId) {
val ends = TypeUtil.getAllEndFeaturesOf(type)
val nonUsageEnds = ends.filter[end | !(end instanceof Usage)]
val ownedNonUsageEnds = nonUsageEnds.filter[end | end.owner === type]
if (!nonUsageEnds.isEmpty) {
if (ownedNonUsageEnds.isEmpty()) {
error(msg, type, null, errorId)
} else {
for (end: ownedNonUsageEnds) {
error(msg, end, null, errorId)
}
}
}
return ends;
}

protected def boolean checkNotAny(Iterable<? extends EObject> list, String msg, EStructuralFeature eFeature, String eId) {
var check = true
for (obj: list) {
Expand Down
Loading
Loading