Skip to content

Commit

Permalink
Added parameter validation to Signal constructors #11
Browse files Browse the repository at this point in the history
  • Loading branch information
ujhelyiz committed Sep 11, 2015
1 parent cb47a74 commit c572477
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -815,26 +815,32 @@ from {
checkrule InstanceCreationExpressionParameter for
InstanceCreationExpression ex
from {
ex.instance instanceof Class
val candidates = umlContext(ex).
getConstructorsOfClass(ex.instance as Class)
switch (ex.instance) {
Class : {
val candidates = umlContext(ex).
getConstructorsOfClass(ex.instance as Class)

val filteredCandidates = candidates.calculateBestCandidates(ex.parameters)
if (candidates.isEmpty) {
if (!(ex.parameters instanceof ExpressionList) || !(ex.parameters as ExpressionList).expressions.isEmpty) {
fail
error "Default constructor cannot have parameters"
source ex.parameters
val filteredCandidates = candidates.calculateBestCandidates(ex.parameters)
if (candidates.isEmpty) {
if (!(ex.parameters instanceof ExpressionList) || !(ex.parameters as ExpressionList).expressions.isEmpty) {
fail
error "Default constructor cannot have parameters"
source ex.parameters
}
} else if (filteredCandidates.isEmpty) {
fail
error "No constructors match parameters"
source ex.parameters
} else if (filteredCandidates.size == 1) {
empty |- filteredCandidates.get(0) <: ex.parameters
} else {
fail
error "Multiple constructor candidates match the parameters"
source ex.parameters
}
}
Signal : {
empty |- (ex.instance as Signal).createVirtualConstructor <: ex.parameters
}
} else if (filteredCandidates.isEmpty) {
fail
error "No constructors match parameters"
source ex.parameters
} else if (filteredCandidates.size == 1) {
empty |- filteredCandidates.get(0) <: ex.parameters
} else {
fail
error "Multiple constructor candidates match the parameters"
source ex.parameters
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,15 @@ protected void createAndAddDiagnostic(Triple<EObject, EReference, INode> triple,
list.add(diagnostic);
}
}

@Override
public void setEagerLinking(boolean eagerLinking) {
//Does not allow turning eager linking off
}

@Override
public boolean isEagerLinking() {
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import org.eclipse.uml2.uml.Behavior
import org.eclipse.uml2.uml.Parameter
import org.eclipse.uml2.uml.ParameterDirectionKind
import org.eclipse.uml2.uml.Operation
import org.eclipse.uml2.uml.Signal
import org.eclipse.uml2.uml.UMLFactory

class UMLScopeHelper {

Expand All @@ -28,4 +30,21 @@ class UMLScopeHelper {
def Parameter getReturnParameter(Operation operation) {
operation?.ownedParameters?.findFirst[direction == ParameterDirectionKind.RETURN_LITERAL]
}

/**
* Returns a virtual (not in the model) operation that has the same signature a signal constructor expects
*/
def Operation createVirtualConstructor(Signal signal) {
val operation = UMLFactory.eINSTANCE.createOperation => [
name = signal.name
ownedParameters.addAll(signal.allAttributes().map [
val parameter = UMLFactory.eINSTANCE.createParameter
parameter.name = it.name
parameter.type = it.type
parameter.direction = ParameterDirectionKind.IN_LITERAL
parameter
])
]
operation
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1019,61 +1019,73 @@ public Result<Boolean> instanceCreationExpressionParameter(final RuleApplication

protected Result<Boolean> instanceCreationExpressionParameterInternal(final RuleApplicationTrace _trace_, final InstanceCreationExpression ex) throws RuleFailedException {
Classifier _instance = ex.getInstance();
/* ex.instance instanceof Class */
if (!(_instance instanceof org.eclipse.uml2.uml.Class)) {
sneakyThrowRuleFailedException("ex.instance instanceof Class");
}
IUMLContextProvider _umlContext = this.typeFactory.umlContext(ex);
Classifier _instance_1 = ex.getInstance();
final Set<Operation> candidates = _umlContext.getConstructorsOfClass(((org.eclipse.uml2.uml.Class) _instance_1));
Tuple _parameters = ex.getParameters();
final List<Operation> filteredCandidates = this.candidateChecker.calculateBestCandidates(candidates, _parameters);
boolean _isEmpty = candidates.isEmpty();
if (_isEmpty) {
boolean _or = false;
Tuple _parameters_1 = ex.getParameters();
boolean _not = (!(_parameters_1 instanceof ExpressionList));
if (_not) {
_or = true;
} else {
Tuple _parameters_2 = ex.getParameters();
EList<Expression> _expressions = ((ExpressionList) _parameters_2).getExpressions();
boolean _isEmpty_1 = _expressions.isEmpty();
boolean _not_1 = (!_isEmpty_1);
_or = _not_1;
}
if (_or) {
/* fail error "Default constructor cannot have parameters" source ex.parameters */
String error = "Default constructor cannot have parameters";
Tuple _parameters_3 = ex.getParameters();
EObject source = _parameters_3;
throwForExplicitFail(error, new ErrorInformation(source, null));
}
} else {
boolean _isEmpty_2 = filteredCandidates.isEmpty();
if (_isEmpty_2) {
/* fail error "No constructors match parameters" source ex.parameters */
String error_1 = "No constructors match parameters";
Tuple _parameters_4 = ex.getParameters();
EObject source_1 = _parameters_4;
throwForExplicitFail(error_1, new ErrorInformation(source_1, null));
} else {
int _size = filteredCandidates.size();
boolean _equals = (_size == 1);
if (_equals) {
/* empty |- filteredCandidates.get(0) <: ex.parameters */
Operation _get = filteredCandidates.get(0);
Tuple _parameters_5 = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, _get, _parameters_5);
boolean _matched = false;
if (!_matched) {
if (_instance instanceof org.eclipse.uml2.uml.Class) {
_matched=true;
IUMLContextProvider _umlContext = this.typeFactory.umlContext(ex);
Classifier _instance_1 = ex.getInstance();
final Set<Operation> candidates = _umlContext.getConstructorsOfClass(((org.eclipse.uml2.uml.Class) _instance_1));
Tuple _parameters = ex.getParameters();
final List<Operation> filteredCandidates = this.candidateChecker.calculateBestCandidates(candidates, _parameters);
boolean _isEmpty = candidates.isEmpty();
if (_isEmpty) {
boolean _or = false;
Tuple _parameters_1 = ex.getParameters();
boolean _not = (!(_parameters_1 instanceof ExpressionList));
if (_not) {
_or = true;
} else {
Tuple _parameters_2 = ex.getParameters();
EList<Expression> _expressions = ((ExpressionList) _parameters_2).getExpressions();
boolean _isEmpty_1 = _expressions.isEmpty();
boolean _not_1 = (!_isEmpty_1);
_or = _not_1;
}
if (_or) {
/* fail error "Default constructor cannot have parameters" source ex.parameters */
String error = "Default constructor cannot have parameters";
Tuple _parameters_3 = ex.getParameters();
EObject source = _parameters_3;
throwForExplicitFail(error, new ErrorInformation(source, null));
}
} else {
/* fail error "Multiple constructor candidates match the parameters" source ex.parameters */
String error_2 = "Multiple constructor candidates match the parameters";
Tuple _parameters_6 = ex.getParameters();
EObject source_2 = _parameters_6;
throwForExplicitFail(error_2, new ErrorInformation(source_2, null));
boolean _isEmpty_2 = filteredCandidates.isEmpty();
if (_isEmpty_2) {
/* fail error "No constructors match parameters" source ex.parameters */
String error_1 = "No constructors match parameters";
Tuple _parameters_4 = ex.getParameters();
EObject source_1 = _parameters_4;
throwForExplicitFail(error_1, new ErrorInformation(source_1, null));
} else {
int _size = filteredCandidates.size();
boolean _equals = (_size == 1);
if (_equals) {
/* empty |- filteredCandidates.get(0) <: ex.parameters */
Operation _get = filteredCandidates.get(0);
Tuple _parameters_5 = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, _get, _parameters_5);
} else {
/* fail error "Multiple constructor candidates match the parameters" source ex.parameters */
String error_2 = "Multiple constructor candidates match the parameters";
Tuple _parameters_6 = ex.getParameters();
EObject source_2 = _parameters_6;
throwForExplicitFail(error_2, new ErrorInformation(source_2, null));
}
}
}
}
}
if (!_matched) {
if (_instance instanceof Signal) {
_matched=true;
/* empty |- (ex.instance as Signal).createVirtualConstructor <: ex.parameters */
Classifier _instance_1 = ex.getInstance();
Operation _createVirtualConstructor = this.scopeHelper.createVirtualConstructor(((Signal) _instance_1));
Tuple _parameters = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, _createVirtualConstructor, _parameters);
}
}
return new Result<Boolean>(true);
}

Expand Down

0 comments on commit c572477

Please sign in to comment.