Skip to content

Commit

Permalink
Issue #99 - Allowed for signal sends and accepts w/o using receptions.
Browse files Browse the repository at this point in the history
  • Loading branch information
seidewitz committed Oct 30, 2020
1 parent ba12bfa commit d4491aa
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 33 deletions.
13 changes: 10 additions & 3 deletions org.modeldriven.alf/Libraries/resources/error-messages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ One or more arguments are not compatible (in type and/or multiplicity) with the
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.)

behaviorInvocationExpressionReferentConstraint
Behavior or feature reference cannot be resolved.
Behavior or feature reference cannot be resolved or arguments are not compatible (in type and/or multiplicity) with corresponding parameters.
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).

binaryExpressionOperandAssignments
Expand Down Expand Up @@ -166,6 +166,9 @@ invocationExpressionAssignmentsAfter
Assignments not allowed in tuple of sequence feature invocation.
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.

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

isUniqueExpressionExpressionArgument
Argument must have a multiplicity upper bound of 1.
Expand Down Expand Up @@ -424,8 +427,12 @@ acceptStatementNewAssignments
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.

acceptStatementSignals
Referenced signals must have receptions; signals cannot be referenced in more than one accept block.
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.
Signals cannot be referenced in more than one accept block.
No signal may be referenced in more than one accept block of an accept statement.

acceptStatementReceptions
Referenced signals must have receptions.
The containing behavior of an accept statement must have receptions for all signals from all accept blocks of the accept statement.

acceptStatementSimpleAcceptLocalName

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

public abstract class AlfBase {

public static final String ALF_VERSION = "1.1.0j";
public static final String ALF_VERSION = "1.1.0k";

protected boolean isVerbose = false;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright 2011-2018 Model Driven Solutions, Inc.
* Copyright 2011-2020 Model Driven Solutions, Inc.
* All rights reserved worldwide. This program and the accompanying materials
* are made available for use under the terms of the GNU General Public License
* (GPL) version 3 that accompanies this distribution and is available at
Expand All @@ -16,12 +16,12 @@
import org.modeldriven.alf.fuml.mapping.ActivityGraph;
import org.modeldriven.alf.fuml.mapping.FumlMapping;
import org.modeldriven.alf.fuml.mapping.common.ElementReferenceMapping;
import org.modeldriven.alf.fuml.mapping.expressions.ExpressionMapping;
import org.modeldriven.alf.fuml.mapping.units.ActivityDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.ClassifierDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.OperationDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.PropertyDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.ReceptionDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.SignalDefinitionMapping;
import org.modeldriven.alf.fuml.mapping.units.SignalReceptionDefinitionMapping;
import org.modeldriven.alf.mapping.Mapping;
import org.modeldriven.alf.mapping.MappingError;
Expand Down Expand Up @@ -295,15 +295,18 @@ public Action mapTarget() throws MappingError {
} else if (mapping instanceof ReceptionDefinitionMapping) {
element = ((ReceptionDefinitionMapping) mapping).getReception();
} else if (mapping instanceof SignalReceptionDefinitionMapping) {
element = ((SignalReceptionDefinitionMapping) mapping).getReception();
element = ((SignalReceptionDefinitionMapping) mapping).getReception();
} else if (mapping instanceof SignalDefinitionMapping) {
// Allow for possible mapping of a signal send without targeting a reception.
element = ((SignalDefinitionMapping)mapping).getSignal();
} else if (mapping instanceof ActivityDefinitionMapping) {
element =
((ActivityDefinitionMapping) mapping).getBehavior();
} else if (mapping instanceof PropertyDefinitionMapping) {
element =
((PropertyDefinitionMapping) mapping).getProperty();
} else {
this.throwError("Unknown referent mapping", mapping);
this.throwError("Unknown referent mapping: " + mapping);
}
}
}
Expand All @@ -314,6 +317,10 @@ public Action mapTarget() throws MappingError {
} else if (element instanceof Reception) {
action = this.graph.addSendSignalAction(((Reception)element).getSignal());

// Allow for possible mapping of a signal send without targeting a reception.
} else if (element instanceof Signal) {
action = this.graph.addSendSignalAction((Signal)element);

} else if (element instanceof Behavior) {
action = this.graph.addCallBehaviorAction((Behavior)element);
this.resultSource = ActivityGraph.getReturnPin(action);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,16 @@ public boolean invocationExpressionAssignmentsAfter() {
}

/**
* The referent of an invocation cannot be a signal unless it is a
* signal reception.
*/
// NOTE: By ignoring violations of this constraint, a tool can allow signal
// sends that directly target signals without requiring the use of receptions.
public boolean invocationExpressionReferent() {
return this.getImpl().invocationExpressionSignalReferent();
}

/**
* Returns references to the elements that act as the parameters of the
* referent. If the referent is a behavior or operation, these are the owned
* parameters, in order. If the referent is an association end, then the
Expand Down Expand Up @@ -352,6 +362,9 @@ public void checkConstraints(Collection<ConstraintViolation> violations) {
if (!this.invocationExpressionAssignmentsAfter()) {
violations.add(new ConstraintViolation("invocationExpressionAssignmentsAfter", this));
}
if (!this.invocationExpressionReferent()) {
violations.add(new ConstraintViolation("invocationExpressionReferent", this));
}
Tuple tuple = this.getTuple();
if (tuple != null) {
tuple.checkConstraints(violations);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright 2011-2017 Model Driven Solutions, Inc.
* Copyright 2011-2020 Model Driven Solutions, Inc.
*
* All rights reserved worldwide. This program and the accompanying materials
* are made available for use under the terms of the GNU General Public License
Expand Down Expand Up @@ -113,7 +113,10 @@ protected Collection<ElementReference> deriveReferent() {
if (!referent.getImpl().isContainedIn(referents)) {
referents.add(referent);
}
}
}

// Allow for the possibility of a signal send without targeting a reception.
referents.addAll(this.currentScope.getImpl().resolveSignal(name));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright 2011-2019 Model Driven Solutions, Inc.
* Copyright 2011-2020 Model Driven Solutions, Inc.
* All rights reserved worldwide. This program and the accompanying materials
* are made available for use under the terms of the GNU General Public License
* (GPL) version 3 that accompanies this distribution and is available at
Expand Down Expand Up @@ -432,6 +432,18 @@ public boolean invocationExpressionAssignmentsAfter() {
tuple.getImpl().getNewAssignments().isEmpty();
}
}

/**
* The referent of an invocation cannot be a signal unless it is a
* signal reception.
*/
// NOTE: By ignoring violations of this constraint, a tool can allow signal
// sends that directly target signals without requiring the use of receptions.
public boolean invocationExpressionSignalReferent() {
ElementReference referent = this.getSelf().getReferent();
return referent == null || !referent.getImpl().isSignal() ||
referent.getImpl().isReception();
}

/*
* Helper Methods
Expand Down Expand Up @@ -551,14 +563,16 @@ public ElementReference parameterNamed(String name, ElementReference referent) {

public ElementReference resolveOverloading(Collection<ElementReference> referents) {
InvocationExpression self = this.getSelf();
List<ElementReference> features = new ArrayList<ElementReference>();
List<ElementReference> features = new ArrayList<ElementReference>();
for (ElementReference referent: referents) {
if ((referent.getImpl().isOperation() ||
referent.getImpl().isReception()) &&
self.getImpl().isCompatibleWith(referent)) {
features.add(referent);
referent.getImpl().isReception() ||
// Allow for the possibility of a signal send without targeting a reception.
referent.getImpl().isSignal()) &&
self.getImpl().isCompatibleWith(referent)) {
features.add(referent);
}
}
}
return selectMostSpecific(features);
}

Expand All @@ -573,17 +587,19 @@ public static ElementReference selectMostSpecific(List<ElementReference> feature
break;
}
}
if (isMostSpecific) {
if (selectedFeature != null) {
return null;
if (isMostSpecific) {
if (selectedFeature == null ||
!selectedFeature.getImpl().isFeature() && feature1.getImpl().isFeature()) {
selectedFeature = feature1;
} else if (!selectedFeature.getImpl().isFeature() || feature1.getImpl().isFeature()) {
return null;
}
selectedFeature = feature1;
}
}
}
return selectedFeature;
}

}

public static boolean isMoreSpecificThan(ElementReference feature1, ElementReference feature2) {
List<ElementReference> parameters1 =
OperationDefinitionImpl.removeReturnParameter(feature1.getImpl().getEffectiveParameters());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright 2011, 2018 Model Driven Solutions, Inc.
* Copyright 2011, 2018, 2020 Model Driven Solutions, Inc.
* All rights reserved worldwide. This program and the accompanying materials
* are made available for use under the terms of the GNU General Public License
* (GPL) version 3 that accompanies this distribution and is available at
Expand Down Expand Up @@ -77,14 +77,20 @@ public boolean acceptStatementContext() {
}

/**
* 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.
* No signal may be referenced in more than one accept block of an accept statement.
**/
public boolean acceptStatementSignals() {
return this.getImpl().acceptStatementSignals();
}

/**
* The containing behavior of an accept statement must have receptions for
* all signals from all accept blocks of the accept statement.
**/
public boolean acceptStatementReceptions() {
return this.getImpl().acceptStatementReceptions();
}

/**
* Any name defined in an accept block of an accept statement must be
* unassigned before the accept statement.
Expand Down Expand Up @@ -199,6 +205,10 @@ public void checkConstraints(Collection<ConstraintViolation> violations) {
violations.add(new ConstraintViolation("acceptStatementSignals",
this));
}
if (!this.acceptStatementReceptions()) {
violations.add(new ConstraintViolation("acceptStatementReceptions",
this));
}
if (!this.acceptStatementNames()) {
violations
.add(new ConstraintViolation("acceptStatementNames", this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

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

/**
* 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.
* No signal may be referenced in more than one accept block of an accept statement.
**/
// NOTE: Checking that there are receptions for the signals has been moved to
// the separate acceptStatementReceptions check.
public boolean acceptStatementSignals() {
ElementReference behavior = this.getEffectiveBehavior();
behavior = behavior == null? null: behavior.getImpl().getContext();
Expand All @@ -195,8 +194,7 @@ public boolean acceptStatementSignals() {
for (AcceptBlock block: this.getSelf().getAcceptBlock()) {
Collection<ElementReference> blockSignals = block.getSignal();
for (ElementReference signal: blockSignals) {
if (!behavior.getImpl().hasReceptionFor(signal) ||
signal.getImpl().isContainedIn(signals)) {
if (signal.getImpl().isContainedIn(signals)) {
return false;
}
}
Expand All @@ -206,6 +204,30 @@ public boolean acceptStatementSignals() {
}
}

/**
* The containing behavior of an accept statement must have receptions for
* all signals from all accept blocks of the accept statement.
**/
// NOTE: acceptStatementSignals has been separated from acceptStatementReceptions
// so that a tool can allow accept statements without requiring receptions by
// ignoring violations of this constraint.
public boolean acceptStatementReceptions() {
ElementReference behavior = this.getEffectiveBehavior();
behavior = behavior == null? null: behavior.getImpl().getContext();
if (behavior == null) {
return false;
} else {
for (AcceptBlock block: this.getSelf().getAcceptBlock()) {
for (ElementReference signal: block.getSignal()) {
if (!behavior.getImpl().hasReceptionFor(signal)) {
return false;
}
}
}
return true;
}
}

/**
* Any name defined in an accept block of an accept statement must be
* unassigned before the accept statement.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,17 @@ public Collection<Member> resolveAsOuterScope(String name, boolean classifierOnl
}

return referents;
}

public Collection<ElementReference> resolveSignal(String name) {
Collection<ElementReference> signals = new ArrayList<>();
for (Member member: this.resolve(name, true)) {
ElementReference referent = member.getImpl().getReferent();
if (referent.getImpl().isSignal() && !referent.getImpl().isReception()) {
signals.add(referent);
}
}
return signals;
}

public boolean isModelLibrary() {
Expand Down

0 comments on commit d4491aa

Please sign in to comment.