Skip to content

Commit 650866f

Browse files
Added new functionality to handle "ExplicitBaseClassCall" stereotype during runtime
1 parent 1f971d8 commit 650866f

File tree

11 files changed

+146
-15
lines changed

11 files changed

+146
-15
lines changed

fUML-CPP/fuml/src/fuml/extensions/structuredclassifiers/SignatureBasedDispatchStrategy.cpp

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
using namespace fuml::extensions::structuredclassifiers;
1515

1616
BehaviorPtr SignatureBasedDispatchStrategy::getMethod(const Object_Ptr& object_, const OperationPtr& operation)
17+
{
18+
return this->getMethod(object_, operation, false);
19+
}
20+
21+
BehaviorPtr SignatureBasedDispatchStrategy::getMethod(const Object_Ptr& object_, const OperationPtr& operation, bool isExplicitBaseClassCall)
1722
{
1823
// Find the member operation of a type of the given object_ that
1924
// is the same as or overrides the given operation. Then
@@ -24,12 +29,31 @@ BehaviorPtr SignatureBasedDispatchStrategy::getMethod(const Object_Ptr& object_,
2429
// the first one is arbitrarily chosen.]
2530

2631
BehaviorPtr method = nullptr;
32+
const Class_Ptr& operationClass = operation->class_.lock();
33+
2734
unsigned int i = 1;
2835
unsigned int sizeOfTypes = object_->types->size();
2936
while (method == nullptr && i <= sizeOfTypes)
3037
{
3138
const Class_Ptr& type = object_->types->at(i - 1);
32-
method = this->getMethod(type, operation);
39+
40+
if(isExplicitBaseClassCall)
41+
{
42+
// The operation call shall explicitly invoke a base class operation,
43+
// even if the operation is overridden by type (or a direct or indirect base class of type).
44+
// This behaves as if object_'s actual type was the type that owns operation,
45+
// if operationClass is a direct or indirect base class of type.
46+
47+
if(operationClass != nullptr && this->isSpecializationOf(type, operationClass))
48+
{
49+
method = this->getMethod(operationClass, operation);
50+
}
51+
}
52+
else
53+
{
54+
method = this->getMethod(type, operation);
55+
}
56+
3357
i++;
3458
}
3559

@@ -71,8 +95,7 @@ BehaviorPtr SignatureBasedDispatchStrategy::getMethod(const Class_Ptr& type, con
7195
unsigned int sizeOfGeneral = general->size();
7296
while(method == nullptr && i <= sizeOfGeneral)
7397
{
74-
const Class_Ptr baseClass = std::dynamic_pointer_cast<Class_>(general->at(i - 1));
75-
if(baseClass)
98+
if(Class_Ptr baseClass = std::dynamic_pointer_cast<Class_>(general->at(i - 1)))
7699
{
77100
method = this->getMethod(baseClass, operation);
78101
}
@@ -115,7 +138,7 @@ bool SignatureBasedDispatchStrategy::operationsMatch(const OperationPtr& ownedOp
115138

116139
matches = ownedOperationReturnType &&
117140
baseOperationReturnType &&
118-
this->isCovariant(ownedOperationReturnType, baseOperationReturnType);
141+
this->isSpecializationOf(ownedOperationReturnType, baseOperationReturnType);
119142
}
120143
else
121144
{
@@ -135,24 +158,24 @@ bool SignatureBasedDispatchStrategy::operationsMatch(const OperationPtr& ownedOp
135158
return matches;
136159
} // operationsMatch
137160

138-
bool SignatureBasedDispatchStrategy::isCovariant(const ClassifierPtr& ownedOperationReturnType, const ClassifierPtr& baseOperationReturnType)
161+
bool SignatureBasedDispatchStrategy::isSpecializationOf(const ClassifierPtr& specializedType, const ClassifierPtr& generalType)
139162
{
140-
bool isCovariant = false;
163+
bool isSpecialized = false;
141164

142165
unsigned int i = 1;
143-
unsigned int sizeOfGeneral = ownedOperationReturnType->general->size();
144-
while (isCovariant == false && i <= sizeOfGeneral)
166+
unsigned int sizeOfGeneral = specializedType->general->size();
167+
while (isSpecialized == false && i <= sizeOfGeneral)
145168
{
146-
const ClassifierPtr& baseType = ownedOperationReturnType->general->at(i - 1);
147-
isCovariant = baseOperationReturnType == baseType;
169+
const ClassifierPtr& directBase = specializedType->general->at(i - 1);
170+
isSpecialized = generalType == directBase;
148171

149-
if(!isCovariant)
172+
if(!isSpecialized)
150173
{
151-
isCovariant = this->isCovariant(baseType, baseOperationReturnType);
174+
isSpecialized = this->isSpecializationOf(directBase, generalType);
152175
}
153176

154177
i++;
155178
}
156179

157-
return isCovariant;
180+
return isSpecialized;
158181
} // isCovariant

fUML-CPP/fuml/src/fuml/extensions/structuredclassifiers/SignatureBasedDispatchStrategy.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ namespace fuml::extensions::structuredclassifiers
1818
virtual ~SignatureBasedDispatchStrategy() = default;
1919

2020
virtual BehaviorPtr getMethod(const Object_Ptr&, const OperationPtr&) override;
21+
virtual BehaviorPtr getMethod(const Object_Ptr&, const OperationPtr&, bool) override;
2122
BehaviorPtr getMethod(const Class_Ptr&, const OperationPtr&);
2223
virtual bool operationsMatch(const OperationPtr&, const OperationPtr&);
23-
bool isCovariant(const ClassifierPtr&, const ClassifierPtr&);
24+
bool isSpecializationOf(const ClassifierPtr&, const ClassifierPtr&);
2425
};
2526
// SignatureBasedDispatchStrategy
2627
}

fUML-CPP/fuml/src/fuml/semantics/actions/CallOperationActionActivation.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ ExecutionPtr CallOperationActionActivation::getCallExecution()
3636
// operation to it and return the resulting execution object.
3737

3838
CallOperationActionPtr action = std::dynamic_pointer_cast<CallOperationAction>(this->node);
39+
bool isExplicitBaseClassCall = this->isExplicitBaseClassCall(action);
3940
ValuePtr target = this->takeTokens(action->target)->at(0);
4041

4142
ExecutionPtr execution;
@@ -44,7 +45,7 @@ ExecutionPtr CallOperationActionActivation::getCallExecution()
4445

4546
if (reference)
4647
{
47-
execution = reference->dispatch(action->operation);
48+
execution = reference->dispatch(action->operation, isExplicitBaseClassCall);
4849
}
4950
else
5051
{

fUML-CPP/fuml/src/fuml/semantics/actions/CallOperationActionActivation.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace fuml::semantics::actions
2020
virtual bool isReady() override;
2121
virtual ExecutionPtr getCallExecution() override;
2222
virtual ParameterListPtr getParameters() override;
23+
bool isExplicitBaseClassCall(const CallOperationActionPtr&); // implemented in CallOperationActionActivationExtension.cpp
2324

2425
};
2526
// CallOperationActionActivation
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* CallOperationActionActivationExtension.cpp
3+
*
4+
* Created on: 17.01.2024
5+
* Author: maha6913
6+
*/
7+
8+
#include <fuml/semantics/actions/CallOperationActionActivation.h>
9+
10+
#include <uml/actions/CallOperationAction.h>
11+
#include <uml/packages/Stereotype.h>
12+
13+
bool CallOperationActionActivation::isExplicitBaseClassCall(const CallOperationActionPtr& callOperationAction)
14+
{
15+
const StereotypeListPtr& appliedStereotypes = callOperationAction->appliedStereotype;
16+
unsigned int i = 0;
17+
unsigned int appliedStereotypesSize = appliedStereotypes->size();
18+
bool isExplicitBaseClassCall = false;
19+
20+
while (i < appliedStereotypesSize && !isExplicitBaseClassCall)
21+
{
22+
const StereotypePtr& s = appliedStereotypes->at(i);
23+
if (s->name == "ExplicitBaseClassCall")
24+
{
25+
isExplicitBaseClassCall = true;
26+
}
27+
}
28+
return isExplicitBaseClassCall;
29+
}

fUML-CPP/fuml/src/fuml/semantics/structuredclassifiers/DispatchStrategy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ namespace fuml::semantics::structuredclassifiers
2020

2121
virtual std::string getName() override;
2222
ExecutionPtr dispatch(const Object_Ptr&, const OperationPtr&);
23+
ExecutionPtr dispatch(const Object_Ptr&, const OperationPtr&, bool); //implemented in DispatchStrategyExtension.cpp
2324
virtual BehaviorPtr getMethod(const Object_Ptr&, const OperationPtr&);
25+
virtual BehaviorPtr getMethod(const Object_Ptr&, const OperationPtr&, bool); // implemented in DispatchStrategyExtension.cpp
2426
};
2527
// DispatchStrategy
2628
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* DispatchStrategyExtension.cpp
3+
*
4+
* Created on: 17.01.2024
5+
* Author: maha6913
6+
*/
7+
8+
#include <fuml/semantics/structuredclassifiers/DispatchStrategy.h>
9+
10+
#include <fuml/semantics/loci/ExecutionFactory.h>
11+
#include <fuml/semantics/loci/Locus.h>
12+
#include <fuml/semantics/structuredclassifiers/Object_.h>
13+
14+
ExecutionPtr DispatchStrategy::dispatch(const Object_Ptr& object, const OperationPtr& operation, bool isExplicitBaseClassCall)
15+
{
16+
// Extends DispatchStrategy::dispatch(const Object_Ptr&, const OperationPtr&) by flag "isExplicitBaseClassCall"
17+
// Propagate "isExplicitBaseClassCall" to DispatchStrategy::getMethod
18+
19+
return object->locus->factory->createExecution(this->getMethod(object, operation, isExplicitBaseClassCall), object);
20+
} // dispatch
21+
22+
BehaviorPtr DispatchStrategy::getMethod(const Object_Ptr& object, const OperationPtr& operation, bool)
23+
{
24+
return this->getMethod(object, operation);
25+
} // getMethod

fUML-CPP/fuml/src/fuml/semantics/structuredclassifiers/Object_.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ namespace fuml::semantics::structuredclassifiers
2727

2828
void startBehavior(const Class_Ptr&, const ParameterValueListPtr&);
2929
virtual ExecutionPtr dispatch(const OperationPtr&);
30+
virtual ExecutionPtr dispatch(const OperationPtr&, bool); // implemented in Object_Extension.cpp
3031
void send(const EventOccurrencePtr&);
3132
virtual void destroy() override;
3233
void register_(const EventAccepterPtr&);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Object_Extension.cpp
3+
*
4+
* Created on: 17.01.2024
5+
* Author: maha6913
6+
*/
7+
8+
#include <fuml/semantics/structuredclassifiers/Object_.h>
9+
10+
#include <fuml/semantics/loci/ExecutionFactory.h>
11+
#include <fuml/semantics/loci/Locus.h>
12+
#include <fuml/semantics/structuredclassifiers/DispatchStrategy.h>
13+
14+
ExecutionPtr Object_::dispatch(const OperationPtr& operation, bool isExplicitBaseClassCall)
15+
{
16+
// Extends Object_::dispatch(const OperationPtr&) by flag "isExplicitBaseClassCall".
17+
// If "isExplicitBaseClassCall" is false, delegate to Object_::dispatch(const OperationPtr&).
18+
// Otherwise, delegate to DispatchStrategy::dispatch(const Object_Ptr&, const OperationPtr&, bool)
19+
20+
if(!isExplicitBaseClassCall)
21+
{
22+
return this->dispatch(operation);
23+
}
24+
25+
DispatchStrategyPtr dispatchStrategy = std::dynamic_pointer_cast<DispatchStrategy>(
26+
this->locus->factory->getStrategy("dispatch"));
27+
28+
return dispatchStrategy->dispatch(this->thisObject_Ptr.lock(), operation, isExplicitBaseClassCall);
29+
} // dispatch

fUML-CPP/fuml/src/fuml/semantics/structuredclassifiers/Reference.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace fuml::semantics::structuredclassifiers
2222

2323
virtual void startBehavior(const Class_Ptr&, const ParameterValueListPtr&);
2424
virtual ExecutionPtr dispatch(const OperationPtr&);
25+
virtual ExecutionPtr dispatch(const OperationPtr&, bool); // implemented in ReferenceExtension.cpp
2526
virtual void send(const EventOccurrencePtr&);
2627
void destroy();
2728
virtual bool equals(const ValuePtr&) override;

0 commit comments

Comments
 (0)