Skip to content

Commit d4491aa

Browse files
committed
Issue #99 - Allowed for signal sends and accepts w/o using receptions.
1 parent ba12bfa commit d4491aa

File tree

9 files changed

+122
-33
lines changed

9 files changed

+122
-33
lines changed

org.modeldriven.alf/Libraries/resources/error-messages.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ One or more arguments are not compatible (in type and/or multiplicity) with the
3939
If the target qualified name does not disambiguate to a feature reference, then each input argument expression must be assignable to its corresponding parameter and each output argument expression must be assignable from its corresponding parameter. (Note that this implies that the type of an argument expression for an inout parameter must be the same as the type of that parameter.)
4040

4141
behaviorInvocationExpressionReferentConstraint
42-
Behavior or feature reference cannot be resolved.
42+
Behavior or feature reference cannot be resolved or arguments are not compatible (in type and/or multiplicity) with corresponding parameters.
4343
If the target qualified name does not disambiguate to a feature reference, then it must resolve to a behavior or an association end. Otherwise it must resolve to a single feature referent according to the overloading resolution rules, unless it is an implicit destructor call (in which case it has no referent).
4444

4545
binaryExpressionOperandAssignments
@@ -166,6 +166,9 @@ invocationExpressionAssignmentsAfter
166166
Assignments not allowed in tuple of sequence feature invocation.
167167
If invocation is a sequence feature invocation, then the assignments after the tuple of the invocation expression must be the same as the assignments before.
168168

169+
invocationExpressionReferent
170+
Feature reference cannot be resolved or arguments are not compatible (in type and/or multiplicity) with corresponding parameters.
171+
The referent of an invocation cannot be a signal unless it is a signal reception.
169172

170173
isUniqueExpressionExpressionArgument
171174
Argument must have a multiplicity upper bound of 1.
@@ -424,8 +427,12 @@ acceptStatementNewAssignments
424427
Any name that is unassigned before an accept statement and is assigned in one or more blocks of the accept statement, has, after the accept statement, a type that is is the effective common ancestor of the types of the name in each block in which it is defined, with a multiplicity lower bound that is the minimum of the lower bound for the name in each block (where it is considered to have multiplicity lower bound of zero for blocks in which it is not defined), and a multiplicity upper bound that is the maximum for the name in each block in which it is defined.
425428

426429
acceptStatementSignals
427-
Referenced signals must have receptions; signals cannot be referenced in more than one accept block.
428-
The containing behavior of an accept statement must have receptions for all signals from all accept blocks of the accept statement. No signal may be referenced in more than one accept block of an accept statement.
430+
Signals cannot be referenced in more than one accept block.
431+
No signal may be referenced in more than one accept block of an accept statement.
432+
433+
acceptStatementReceptions
434+
Referenced signals must have receptions.
435+
The containing behavior of an accept statement must have receptions for all signals from all accept blocks of the accept statement.
429436

430437
acceptStatementSimpleAcceptLocalName
431438

org.modeldriven.alf/src/org/modeldriven/alf/execution/AlfBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
public abstract class AlfBase {
2626

27-
public static final String ALF_VERSION = "1.1.0j";
27+
public static final String ALF_VERSION = "1.1.0k";
2828

2929
protected boolean isVerbose = false;
3030

org.modeldriven.alf/src/org/modeldriven/alf/fuml/mapping/expressions/InvocationExpressionMapping.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright 2011-2018 Model Driven Solutions, Inc.
2+
* Copyright 2011-2020 Model Driven Solutions, Inc.
33
* All rights reserved worldwide. This program and the accompanying materials
44
* are made available for use under the terms of the GNU General Public License
55
* (GPL) version 3 that accompanies this distribution and is available at
@@ -16,12 +16,12 @@
1616
import org.modeldriven.alf.fuml.mapping.ActivityGraph;
1717
import org.modeldriven.alf.fuml.mapping.FumlMapping;
1818
import org.modeldriven.alf.fuml.mapping.common.ElementReferenceMapping;
19-
import org.modeldriven.alf.fuml.mapping.expressions.ExpressionMapping;
2019
import org.modeldriven.alf.fuml.mapping.units.ActivityDefinitionMapping;
2120
import org.modeldriven.alf.fuml.mapping.units.ClassifierDefinitionMapping;
2221
import org.modeldriven.alf.fuml.mapping.units.OperationDefinitionMapping;
2322
import org.modeldriven.alf.fuml.mapping.units.PropertyDefinitionMapping;
2423
import org.modeldriven.alf.fuml.mapping.units.ReceptionDefinitionMapping;
24+
import org.modeldriven.alf.fuml.mapping.units.SignalDefinitionMapping;
2525
import org.modeldriven.alf.fuml.mapping.units.SignalReceptionDefinitionMapping;
2626
import org.modeldriven.alf.mapping.Mapping;
2727
import org.modeldriven.alf.mapping.MappingError;
@@ -295,15 +295,18 @@ public Action mapTarget() throws MappingError {
295295
} else if (mapping instanceof ReceptionDefinitionMapping) {
296296
element = ((ReceptionDefinitionMapping) mapping).getReception();
297297
} else if (mapping instanceof SignalReceptionDefinitionMapping) {
298-
element = ((SignalReceptionDefinitionMapping) mapping).getReception();
298+
element = ((SignalReceptionDefinitionMapping) mapping).getReception();
299+
} else if (mapping instanceof SignalDefinitionMapping) {
300+
// Allow for possible mapping of a signal send without targeting a reception.
301+
element = ((SignalDefinitionMapping)mapping).getSignal();
299302
} else if (mapping instanceof ActivityDefinitionMapping) {
300303
element =
301304
((ActivityDefinitionMapping) mapping).getBehavior();
302305
} else if (mapping instanceof PropertyDefinitionMapping) {
303306
element =
304307
((PropertyDefinitionMapping) mapping).getProperty();
305308
} else {
306-
this.throwError("Unknown referent mapping", mapping);
309+
this.throwError("Unknown referent mapping: " + mapping);
307310
}
308311
}
309312
}
@@ -314,6 +317,10 @@ public Action mapTarget() throws MappingError {
314317
} else if (element instanceof Reception) {
315318
action = this.graph.addSendSignalAction(((Reception)element).getSignal());
316319

320+
// Allow for possible mapping of a signal send without targeting a reception.
321+
} else if (element instanceof Signal) {
322+
action = this.graph.addSendSignalAction((Signal)element);
323+
317324
} else if (element instanceof Behavior) {
318325
action = this.graph.addCallBehaviorAction((Behavior)element);
319326
this.resultSource = ActivityGraph.getReturnPin(action);

org.modeldriven.alf/src/org/modeldriven/alf/syntax/expressions/InvocationExpression.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,16 @@ public boolean invocationExpressionAssignmentsAfter() {
253253
}
254254

255255
/**
256+
* The referent of an invocation cannot be a signal unless it is a
257+
* signal reception.
258+
*/
259+
// NOTE: By ignoring violations of this constraint, a tool can allow signal
260+
// sends that directly target signals without requiring the use of receptions.
261+
public boolean invocationExpressionReferent() {
262+
return this.getImpl().invocationExpressionSignalReferent();
263+
}
264+
265+
/**
256266
* Returns references to the elements that act as the parameters of the
257267
* referent. If the referent is a behavior or operation, these are the owned
258268
* parameters, in order. If the referent is an association end, then the
@@ -352,6 +362,9 @@ public void checkConstraints(Collection<ConstraintViolation> violations) {
352362
if (!this.invocationExpressionAssignmentsAfter()) {
353363
violations.add(new ConstraintViolation("invocationExpressionAssignmentsAfter", this));
354364
}
365+
if (!this.invocationExpressionReferent()) {
366+
violations.add(new ConstraintViolation("invocationExpressionReferent", this));
367+
}
355368
Tuple tuple = this.getTuple();
356369
if (tuple != null) {
357370
tuple.checkConstraints(violations);

org.modeldriven.alf/src/org/modeldriven/alf/syntax/expressions/impl/FeatureReferenceImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright 2011-2017 Model Driven Solutions, Inc.
2+
* Copyright 2011-2020 Model Driven Solutions, Inc.
33
*
44
* All rights reserved worldwide. This program and the accompanying materials
55
* are made available for use under the terms of the GNU General Public License
@@ -113,7 +113,10 @@ protected Collection<ElementReference> deriveReferent() {
113113
if (!referent.getImpl().isContainedIn(referents)) {
114114
referents.add(referent);
115115
}
116-
}
116+
}
117+
118+
// Allow for the possibility of a signal send without targeting a reception.
119+
referents.addAll(this.currentScope.getImpl().resolveSignal(name));
117120
}
118121
}
119122
}

org.modeldriven.alf/src/org/modeldriven/alf/syntax/expressions/impl/InvocationExpressionImpl.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright 2011-2019 Model Driven Solutions, Inc.
2+
* Copyright 2011-2020 Model Driven Solutions, Inc.
33
* All rights reserved worldwide. This program and the accompanying materials
44
* are made available for use under the terms of the GNU General Public License
55
* (GPL) version 3 that accompanies this distribution and is available at
@@ -432,6 +432,18 @@ public boolean invocationExpressionAssignmentsAfter() {
432432
tuple.getImpl().getNewAssignments().isEmpty();
433433
}
434434
}
435+
436+
/**
437+
* The referent of an invocation cannot be a signal unless it is a
438+
* signal reception.
439+
*/
440+
// NOTE: By ignoring violations of this constraint, a tool can allow signal
441+
// sends that directly target signals without requiring the use of receptions.
442+
public boolean invocationExpressionSignalReferent() {
443+
ElementReference referent = this.getSelf().getReferent();
444+
return referent == null || !referent.getImpl().isSignal() ||
445+
referent.getImpl().isReception();
446+
}
435447

436448
/*
437449
* Helper Methods
@@ -551,14 +563,16 @@ public ElementReference parameterNamed(String name, ElementReference referent) {
551563

552564
public ElementReference resolveOverloading(Collection<ElementReference> referents) {
553565
InvocationExpression self = this.getSelf();
554-
List<ElementReference> features = new ArrayList<ElementReference>();
566+
List<ElementReference> features = new ArrayList<ElementReference>();
555567
for (ElementReference referent: referents) {
556568
if ((referent.getImpl().isOperation() ||
557-
referent.getImpl().isReception()) &&
558-
self.getImpl().isCompatibleWith(referent)) {
559-
features.add(referent);
569+
referent.getImpl().isReception() ||
570+
// Allow for the possibility of a signal send without targeting a reception.
571+
referent.getImpl().isSignal()) &&
572+
self.getImpl().isCompatibleWith(referent)) {
573+
features.add(referent);
560574
}
561-
}
575+
}
562576
return selectMostSpecific(features);
563577
}
564578

@@ -573,17 +587,19 @@ public static ElementReference selectMostSpecific(List<ElementReference> feature
573587
break;
574588
}
575589
}
576-
if (isMostSpecific) {
577-
if (selectedFeature != null) {
578-
return null;
590+
if (isMostSpecific) {
591+
if (selectedFeature == null ||
592+
!selectedFeature.getImpl().isFeature() && feature1.getImpl().isFeature()) {
593+
selectedFeature = feature1;
594+
} else if (!selectedFeature.getImpl().isFeature() || feature1.getImpl().isFeature()) {
595+
return null;
579596
}
580-
selectedFeature = feature1;
581597
}
582598
}
583599
}
584600
return selectedFeature;
585-
}
586-
601+
}
602+
587603
public static boolean isMoreSpecificThan(ElementReference feature1, ElementReference feature2) {
588604
List<ElementReference> parameters1 =
589605
OperationDefinitionImpl.removeReturnParameter(feature1.getImpl().getEffectiveParameters());

org.modeldriven.alf/src/org/modeldriven/alf/syntax/statements/AcceptStatement.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright 2011, 2018 Model Driven Solutions, Inc.
2+
* Copyright 2011, 2018, 2020 Model Driven Solutions, Inc.
33
* All rights reserved worldwide. This program and the accompanying materials
44
* are made available for use under the terms of the GNU General Public License
55
* (GPL) version 3 that accompanies this distribution and is available at
@@ -77,14 +77,20 @@ public boolean acceptStatementContext() {
7777
}
7878

7979
/**
80-
* The containing behavior of an accept statement must have receptions for
81-
* all signals from all accept blocks of the accept statement. No signal may
82-
* be referenced in more than one accept block of an accept statement.
80+
* No signal may be referenced in more than one accept block of an accept statement.
8381
**/
8482
public boolean acceptStatementSignals() {
8583
return this.getImpl().acceptStatementSignals();
8684
}
8785

86+
/**
87+
* The containing behavior of an accept statement must have receptions for
88+
* all signals from all accept blocks of the accept statement.
89+
**/
90+
public boolean acceptStatementReceptions() {
91+
return this.getImpl().acceptStatementReceptions();
92+
}
93+
8894
/**
8995
* Any name defined in an accept block of an accept statement must be
9096
* unassigned before the accept statement.
@@ -199,6 +205,10 @@ public void checkConstraints(Collection<ConstraintViolation> violations) {
199205
violations.add(new ConstraintViolation("acceptStatementSignals",
200206
this));
201207
}
208+
if (!this.acceptStatementReceptions()) {
209+
violations.add(new ConstraintViolation("acceptStatementReceptions",
210+
this));
211+
}
202212
if (!this.acceptStatementNames()) {
203213
violations
204214
.add(new ConstraintViolation("acceptStatementNames", this));

org.modeldriven.alf/src/org/modeldriven/alf/syntax/statements/impl/AcceptStatementImpl.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
/*******************************************************************************
3-
* Copyright 2011, 2016 Model Driven Solutions, Inc.
4-
* Copyright 2013 Ivar Jacobson International
3+
* Copyright 2011, 2016, 2020 Model Driven Solutions, Inc.
54
*
65
* All rights reserved worldwide. This program and the accompanying materials
76
* are made available for use under the terms of the GNU General Public License
@@ -181,10 +180,10 @@ public boolean acceptStatementContext() {
181180
}
182181

183182
/**
184-
* The containing behavior of an accept statement must have receptions for
185-
* all signals from all accept blocks of the accept statement. No signal may
186-
* be referenced in more than one accept block of an accept statement.
183+
* No signal may be referenced in more than one accept block of an accept statement.
187184
**/
185+
// NOTE: Checking that there are receptions for the signals has been moved to
186+
// the separate acceptStatementReceptions check.
188187
public boolean acceptStatementSignals() {
189188
ElementReference behavior = this.getEffectiveBehavior();
190189
behavior = behavior == null? null: behavior.getImpl().getContext();
@@ -195,8 +194,7 @@ public boolean acceptStatementSignals() {
195194
for (AcceptBlock block: this.getSelf().getAcceptBlock()) {
196195
Collection<ElementReference> blockSignals = block.getSignal();
197196
for (ElementReference signal: blockSignals) {
198-
if (!behavior.getImpl().hasReceptionFor(signal) ||
199-
signal.getImpl().isContainedIn(signals)) {
197+
if (signal.getImpl().isContainedIn(signals)) {
200198
return false;
201199
}
202200
}
@@ -206,6 +204,30 @@ public boolean acceptStatementSignals() {
206204
}
207205
}
208206

207+
/**
208+
* The containing behavior of an accept statement must have receptions for
209+
* all signals from all accept blocks of the accept statement.
210+
**/
211+
// NOTE: acceptStatementSignals has been separated from acceptStatementReceptions
212+
// so that a tool can allow accept statements without requiring receptions by
213+
// ignoring violations of this constraint.
214+
public boolean acceptStatementReceptions() {
215+
ElementReference behavior = this.getEffectiveBehavior();
216+
behavior = behavior == null? null: behavior.getImpl().getContext();
217+
if (behavior == null) {
218+
return false;
219+
} else {
220+
for (AcceptBlock block: this.getSelf().getAcceptBlock()) {
221+
for (ElementReference signal: block.getSignal()) {
222+
if (!behavior.getImpl().hasReceptionFor(signal)) {
223+
return false;
224+
}
225+
}
226+
}
227+
return true;
228+
}
229+
}
230+
209231
/**
210232
* Any name defined in an accept block of an accept statement must be
211233
* unassigned before the accept statement.

org.modeldriven.alf/src/org/modeldriven/alf/syntax/units/impl/NamespaceDefinitionImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,17 @@ public Collection<Member> resolveAsOuterScope(String name, boolean classifierOnl
464464
}
465465

466466
return referents;
467+
}
468+
469+
public Collection<ElementReference> resolveSignal(String name) {
470+
Collection<ElementReference> signals = new ArrayList<>();
471+
for (Member member: this.resolve(name, true)) {
472+
ElementReference referent = member.getImpl().getReferent();
473+
if (referent.getImpl().isSignal() && !referent.getImpl().isReception()) {
474+
signals.add(referent);
475+
}
476+
}
477+
return signals;
467478
}
468479

469480
public boolean isModelLibrary() {

0 commit comments

Comments
 (0)