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
32 changes: 20 additions & 12 deletions kerml/src/examples/Simple Tests/Redefinition.kerml
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package Redefinition {
class Occurrence;
class Transfer {
feature transferSource;
feature item;
assoc SourceOutputLink specializes Objects::BinaryLinkObject {
end [1] feature source: Occurrence;
end [1..*] feature target: Occurrence;
}
connector sourceOutputLink: SourceOutputLink[1..*] from transferSource to item {
feature startShot: Occurrence redefines SourceOutputLink::startShot;
feature endShot: Occurrence redefines SourceOutputLink::endShot;
}

classifier A {
feature f;
}

classifier B specializes A {
feature redefines f {
feature g;
}
}

classifier C specializes A, B {
feature subsets f {
feature redefines g;
}
}

class X {
feature redefines startShot;
feature redefines endShot;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//* XPECT_SETUP org.omg.kerml.xpect.tests.parsing.KerMLParsingTest
ResourceSet {
ThisFile {}
File {from ="/library/Base.kerml"}
File {from ="/library/Links.kerml"}
File {from ="/library/Occurrences.kerml"}
}
Workspace {
JavaProject {
SrcFolder {
ThisFile {}
File {from ="/library/Base.kerml"}
File {from ="/library/Links.kerml"}
File {from ="/library/Occurrences.kerml"}
}
}
}
END_SETUP
*/

// XPECT noErrors ---> ""
package Redefinition {

classifier A {
feature f;
}

classifier B specializes A {
feature redefines f {
feature g;
}
}

classifier C specializes A, B {
feature subsets f {
feature redefines g;
}
}

class X {
feature redefines startShot;
feature redefines endShot;
}
}
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-2022,2024 Model Driven Solutions, Inc.
* Copyright (c) 2018-2022, 2024, 2025 Model Driven Solutions, Inc.
* Copyright (c) 2018-2020 California Institute of Technology/Jet Propulsion Laboratory
*
* This program is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -123,9 +123,9 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
protected QualifiedName targetqn;

/**
* A map of Elements to the QualifiedNames found for them in the scope.
* A map of QualifiedNames to the Elements resolved for them in the scope.
*/
protected Map<Element, Set<QualifiedName>> elements
protected Map<QualifiedName, Set<Element>> elements

/**
* The QualifiedNames that have already been seen during a resolution search.
Expand Down Expand Up @@ -200,8 +200,8 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
this.elements = newHashMap
this.visitedqns = newHashSet
resolve()
elements.keySet.flatMap[key |
elements.get(key).map[qn | EObjectDescription.create(qn, key)]
elements.keySet.flatMap[qn |
elements.get(qn).map[elm | EObjectDescription.create(qn, elm)]
]
}

Expand Down Expand Up @@ -231,18 +231,22 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
}

protected def boolean addName(QualifiedName qn, Membership mem, Element elm) {
var el = elm
if (referenceType !== SysMLPackage.eINSTANCE.membership && !referenceType.isInstance(el)) {
if (referenceType !== SysMLPackage.eINSTANCE.membership && !referenceType.isInstance(elm)) {
return false
} else {
if (findFirst && referenceType === SysMLPackage.eINSTANCE.membership) {
el = mem
}
val qns = elements.get(el)
if (qns === null) {
elements.put(el, newHashSet(qn))
val el = if (findFirst && referenceType === SysMLPackage.eINSTANCE.membership) mem else elm
val elms = elements.get(qn)
if (elms === null) {
elements.put(qn, newHashSet(el))
} else if (findFirst && el instanceof Feature) {
// If findFirst = true then the only time multiple elements will be added for the same qualified
// name is during the traversal of general types. In this case, the chosen element should be one
// that is not redefined by any other element for the qualified name.
if (elms.exists[old | FeatureUtil.getAllRedefinedFeaturesOf(el as Feature).contains(old)]) {
elements.put(qn, newHashSet(el))
}
} else {
qns.add(qn)
elms.add(el)
}
return true
}
Expand Down Expand Up @@ -326,13 +330,8 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
protected def addQualifiedName(QualifiedName elementqn, Membership mem, Element memberElement) {
visitedqns.add(elementqn)
if (targetqn === null || targetqn == elementqn) {
if (addName(elementqn, mem, memberElement)) {
if (targetqn != elementqn && memberElement instanceof Namespace) {
isShadowing = true
}
if (findFirst && targetqn == elementqn) {
return true
}
if (addName(elementqn, mem, memberElement) && findFirst && targetqn !== null) {
return true;
}
}
false
Expand All @@ -358,6 +357,7 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
}

protected def boolean gen(Namespace ns, QualifiedName qn, Set<Namespace> visited, Set<Element> redefined, boolean isInheriting, boolean includeImplicit) {
var isFound = false
if (ns instanceof Type) {
val conjugator = ns.ownedConjugator
if (conjugator !== null && !scopeProvider.visited.contains(conjugator)) {
Expand All @@ -373,15 +373,19 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
newRedefined.addAll(redefined)
newRedefined.addAll(TypeUtil.getFeaturesRedefinedBy(ns, skip))
}

// Note: All specializations are traversed, even if a resolution is found, in order to check for possible redefinitions inherited
// from subsequent specializations. If findFirst = true, the selection of a single element is handled in addName.

for (e: ns.ownedSpecialization) {
if (!scopeProvider.visited.contains(e)) {
// NOTE: Exclude the generalization e to avoid possible circular name resolution
// NOTE: Exclude the specialization e to avoid possible circular name resolution
// when resolving a proxy for e.general.
scopeProvider.addVisited(e)
val found = e.general.resolveIfUnvisited(qn, false, visited, newRedefined, isInheriting, false, includeImplicit, false)
scopeProvider.removeVisited(e)
if (found) {
return true
isFound = true
}
}
}
Expand All @@ -392,19 +396,19 @@ class KerMLScope extends AbstractScope implements ISysMLScope {
for (type : implicitTypes) {
val found = type.resolveIfUnvisited(qn, false, visited, newRedefined, isInheriting, false, true, false)
if (found) {
return true
isFound = true
}
}
}
if (ns instanceof Feature) {
val chainingFeature = FeatureUtil.getLastChainingFeatureOf(ns)
if (chainingFeature !== null &&
chainingFeature.resolveIfUnvisited(qn, false, visited, newRedefined, isInheriting, false, true, false)) {
return true;
isFound = true;
}
}
}
return false
return isFound
}

protected def boolean imp(Namespace ns, QualifiedName qn, Set<Namespace> visited, boolean isInsideScope, boolean includeImplicitGen, boolean includeAll) {
Expand Down
72 changes: 70 additions & 2 deletions sysml.library/.index.json
Original file line number Diff line number Diff line change
Expand Up @@ -90772,8 +90772,76 @@
"~Port"
],
"Interfaces::Interface::participant::thisParticipant": [
"differencesOf",
"dispatchScope",
"enactedPerformances",
"endShot",
"immediatePredecessors",
"immediateSuccessors",
"incomingTransferSort",
"incomingTransfers",
"incomingTransfersToSelf",
"innerSpaceDimension",
"innerSpaceOccurrences",
"interfacingPorts",
"intersectionsOf",
"involvingPerformances",
"isClosed",
"isDispatch",
"isRunToCompletion",
"justOutsideOfOccurrences",
"largerSpace",
"localClock",
"longerOccurrence",
"matingOccurrences",
"middleTimeSlice",
"outerSpaceDimension",
"outgoingTransfers",
"outgoingTransfersFromSelf",
"outsideOfOccurrences",
"ownedPerformances",
"portionOf",
"portionOfLife",
"portions",
"predecessors",
"runToCompletionScope",
"sameLifeOccurrences",
"self",
"that"
"shorterOccurrence",
"smallerSpace",
"snapshotOf",
"snapshots",
"spaceBoundary",
"spaceBoundaryOf",
"spaceEnclosedOccurrences",
"spaceInterior",
"spaceInteriorOf",
"spaceShotOf",
"spaceShots",
"spaceSliceOf",
"spaceSlices",
"spaceTimeCoincidentOccurrences",
"spaceTimeEnclosedOccurrences",
"spaceTimeEnclosedPoints",
"startShot",
"structuredSpaceBoundary",
"subobjects",
"suboccurrences",
"subports",
"successors",
"superoccurrence",
"surroundedByOccurrences",
"that",
"thatOccurrence",
"this",
"thisOccurrence",
"timeCoincidentOccurrences",
"timeEnclosedOccurrences",
"timeSliceOf",
"timeSlices",
"unionsOf",
"withoutOccurrences",
"~Port"
],
"Interfaces::binaryInterfaces": [
"boundingShapes",
Expand Down Expand Up @@ -280122,5 +280190,5 @@
"withoutOccurrences"
]
},
"checksum": "13b28eb14a5a3cf09e96c180e81b2b10f51730a11d8389122e1345a11525c9c2"
"checksum": "83ebd85a5305dcef0cc1f3f11c219737ad8f38448d8bc28af253c0a2d8af413e"
}
4 changes: 2 additions & 2 deletions sysml.library/Domain Libraries/Geometry/ShapeItems.sysml
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ standard library package ShapeItems {
item :>> edges [1];
}
item :>> edges : Ellipse [1] = shape {
attribute :>> edges::innerSpaceDimension, Ellipse::innerSpaceDimension;
ref item :>> edges::vertices, Ellipse::vertices;
attribute :>> Shell::edges::innerSpaceDimension, Ellipse::innerSpaceDimension;
ref item :>> Shell::edges::vertices, Ellipse::vertices;
}
item :>> vertices [0];
}
Expand Down