Skip to content

Commit

Permalink
Enhanced parameter validation #11
Browse files Browse the repository at this point in the history
Now static methods are also supported
Better validation in place
  • Loading branch information
ujhelyiz committed Sep 11, 2015
1 parent 338c2ce commit 436c6c1
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,54 @@ import com.incquerylabs.uml.ralf.reducedAlfLanguage.AssignmentExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.AssociationAccessExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.BooleanLiteralExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.BooleanUnaryExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.CastExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ClassExtentExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ConditionalLogicalExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ConditionalTestExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.FilterVariable
import com.incquerylabs.uml.ralf.reducedAlfLanguage.DoStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ElementCollectionExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.EqualityExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.Expression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ExpressionList
import com.incquerylabs.uml.ralf.reducedAlfLanguage.FeatureInvocationExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.FilterExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.FilterVariable
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ForEachStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ForStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.IfClause
import com.incquerylabs.uml.ralf.reducedAlfLanguage.InstanceCreationExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.InstanceDeletionExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LeftHandSide
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LinkOperation
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LinkOperationExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LocalNameDeclarationStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LogicalExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LoopVariable
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NameExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NamedTuple
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NaturalLiteralExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NullExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NumericUnaryExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.PostfixExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.PrefixExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.RealLiteralExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.RelationalExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ReturnStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SendSignalStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ShiftExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SignalDataExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.StaticFeatureInvocationExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.StringLiteralExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SwitchClause
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SwitchStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ThisExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.Tuple
import com.incquerylabs.uml.ralf.reducedAlfLanguage.TypeDeclaration
import com.incquerylabs.uml.ralf.reducedAlfLanguage.Variable
import com.incquerylabs.uml.ralf.reducedAlfLanguage.WhileStatement
import com.incquerylabs.uml.ralf.scoping.IUMLContextProvider
import com.incquerylabs.uml.ralf.scoping.UMLScopeHelper
import com.incquerylabs.uml.ralf.types.AbstractTypeReference
import com.incquerylabs.uml.ralf.types.CollectionTypeReference
import com.incquerylabs.uml.ralf.types.IUMLTypeReference
import com.incquerylabs.uml.ralf.types.IUMLTypeReference.AnyTypeReference
Expand All @@ -51,29 +67,13 @@ import org.eclipse.emf.ecore.EObject
import org.eclipse.uml2.uml.Association
import org.eclipse.uml2.uml.Class
import org.eclipse.uml2.uml.Classifier
import org.eclipse.uml2.uml.Operation
import org.eclipse.uml2.uml.Parameter
import org.eclipse.uml2.uml.ParameterDirectionKind
import org.eclipse.uml2.uml.PrimitiveType
import org.eclipse.uml2.uml.Property
import org.eclipse.uml2.uml.Signal
import org.eclipse.uml2.uml.Type
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ForEachStatement
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NullExpression
import com.incquerylabs.uml.ralf.types.AbstractTypeReference
import org.eclipse.uml2.uml.Parameter
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ReturnStatement
import com.incquerylabs.uml.ralf.scoping.UMLScopeHelper
import com.incquerylabs.uml.ralf.reducedAlfLanguage.FeatureInvocationExpression
import org.eclipse.uml2.uml.Operation
import com.incquerylabs.uml.ralf.reducedAlfLanguage.Tuple
import com.incquerylabs.uml.ralf.reducedAlfLanguage.NamedTuple
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ExpressionList
import com.incquerylabs.uml.ralf.reducedAlfLanguage.InstanceDeletionExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.StaticFeatureInvocationExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.IfClause
import org.eclipse.uml2.uml.Property
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LeftHandSide
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SignalDataExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ClassExtentExpression
import com.incquerylabs.uml.ralf.reducedAlfLanguage.CastExpression
import org.eclipse.uml2.uml.ParameterDirectionKind

inject extension TypeFactory typeFactory
inject extension UMLScopeHelper scopeHelper
Expand Down Expand Up @@ -308,13 +308,28 @@ from {
rule NamedTupleTyping
G |- Operation op <: NamedTuple params
from {
val paramMap = <String, Expression> newHashMap(params.expressions.map[it.name -> it.expression])

op.ownedParameters.filter[direction != ParameterDirectionKind.RETURN_LITERAL].forEach[
val paramExpression = paramMap.get(it.name)
val declaredType = it.type.typeReference
G |- paramExpression |> declaredType
]
val exprMap = <String, Expression> newHashMap(params.expressions.map[it.name -> it.expression])
val paramMap = <String, Type> newHashMap(op.ownedParameters.filter[direction != ParameterDirectionKind.RETURN_LITERAL].map[
it.name -> it.type
])
val problematicValues = exprMap.filter[name, expr|
val declaredType = paramMap.get(name)
expr == null ||
declaredType == null ||
!{G |- expr |> declaredType.typeReference}
]
val problematicDeclarations = paramMap.filter[name, declaredType|
val expr = exprMap.get(name)
declaredType == null ||
expr == null ||
!{G |- expr |> declaredType.typeReference}
]
if(problematicValues.size > 0) {
fail
}
if (problematicDeclarations.size > 0) {
fail
}
}

/**
Expand Down Expand Up @@ -776,5 +791,21 @@ from {
checkrule OperationParameters for
FeatureInvocationExpression ex
from {

{
ex.^feature instanceof Operation
empty |- (ex.^feature as Operation) <: ex.parameters
} or {
}
}

checkrule StaticOperationParameters for
StaticFeatureInvocationExpression ex
from {
{
ex.operation instanceof Operation
empty |- (ex.operation as Operation) <: ex.parameters
} or {
ex.operation.reference instanceof Operation
empty |- (ex.operation.reference as Operation) <: ex.parameters
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private boolean operationRedefines(Operation op, Operation redefinedOp) {

private boolean operationMatchesParameters(Operation op, Tuple parameters) {
Result<Boolean> result = typeSystem.operationParametersType(op, parameters);
return !result.failed();
return !result.failed() && result.getValue();
}

@Inject
Expand All @@ -80,8 +80,8 @@ public List<EObject> getLinkedObjects(EObject context, EReference ref, INode nod
Expression ctx = featureInvocationExpression.getContext();
parameters = featureInvocationExpression.getParameters();
contextType = typeSystem.type(ctx).getValue().getUmlType();
} else if (context instanceof StaticFeatureInvocationExpression) {
StaticFeatureInvocationExpression staticFeatureInvocationExpression = (StaticFeatureInvocationExpression) context;
} else if (context.eContainer() instanceof StaticFeatureInvocationExpression) {
StaticFeatureInvocationExpression staticFeatureInvocationExpression = (StaticFeatureInvocationExpression) context.eContainer();
parameters = staticFeatureInvocationExpression.getParameters();
contextType = op.getClass_();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
import it.xsemantics.runtime.XsemanticsRuntimeSystem;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.uml2.uml.Association;
Expand All @@ -90,8 +90,10 @@
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.MapExtensions;
import org.eclipse.xtext.xbase.lib.Pair;

@SuppressWarnings("all")
Expand Down Expand Up @@ -925,6 +927,67 @@ public Result<Boolean> operationParameters(final RuleApplicationTrace _trace_, f
}

protected Result<Boolean> operationParametersInternal(final RuleApplicationTrace _trace_, final FeatureInvocationExpression ex) throws RuleFailedException {
/* { ex.^feature instanceof Operation empty |- (ex.^feature as Operation) <: ex.parameters } or { } */
{
RuleFailedException previousFailure = null;
try {
Feature _feature = ex.getFeature();
/* ex.^feature instanceof Operation */
if (!(_feature instanceof Operation)) {
sneakyThrowRuleFailedException("ex.^feature instanceof Operation");
}
/* empty |- (ex.^feature as Operation) <: ex.parameters */
Feature _feature_1 = ex.getFeature();
Tuple _parameters = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, ((Operation) _feature_1), _parameters);
} catch (Exception e) {
previousFailure = extractRuleFailedException(e);
}
}
return new Result<Boolean>(true);
}

public Result<Boolean> staticOperationParameters(final StaticFeatureInvocationExpression ex) {
return staticOperationParameters(null, ex);
}

public Result<Boolean> staticOperationParameters(final RuleApplicationTrace _trace_, final StaticFeatureInvocationExpression ex) {
try {
return staticOperationParametersInternal(_trace_, ex);
} catch (Exception _e_StaticOperationParameters) {
return resultForFailure(_e_StaticOperationParameters);
}
}

protected Result<Boolean> staticOperationParametersInternal(final RuleApplicationTrace _trace_, final StaticFeatureInvocationExpression ex) throws RuleFailedException {
/* { ex.operation instanceof Operation empty |- (ex.operation as Operation) <: ex.parameters } or { ex.operation.reference instanceof Operation empty |- (ex.operation.reference as Operation) <: ex.parameters } */
{
RuleFailedException previousFailure = null;
try {
NameExpression _operation = ex.getOperation();
/* ex.operation instanceof Operation */
if (!(_operation instanceof Operation)) {
sneakyThrowRuleFailedException("ex.operation instanceof Operation");
}
/* empty |- (ex.operation as Operation) <: ex.parameters */
NameExpression _operation_1 = ex.getOperation();
Tuple _parameters = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, ((Operation) _operation_1), _parameters);
} catch (Exception e) {
previousFailure = extractRuleFailedException(e);
NameExpression _operation_2 = ex.getOperation();
NamedElement _reference = _operation_2.getReference();
/* ex.operation.reference instanceof Operation */
if (!(_reference instanceof Operation)) {
sneakyThrowRuleFailedException("ex.operation.reference instanceof Operation");
}
/* empty |- (ex.operation.reference as Operation) <: ex.parameters */
NameExpression _operation_3 = ex.getOperation();
NamedElement _reference_1 = _operation_3.getReference();
Tuple _parameters_1 = ex.getParameters();
operationParametersTypeInternal(emptyEnvironment(), _trace_, ((Operation) _reference_1), _parameters_1);
}
}
return new Result<Boolean>(true);
}

Expand Down Expand Up @@ -2043,22 +2106,86 @@ protected Result<Boolean> applyRuleNamedTupleTyping(final RuleEnvironment G, fin
return Pair.<String, Expression>of(_name, _expression);
};
List<Pair<? extends String, ? extends Expression>> _map = ListExtensions.<NamedExpression, Pair<? extends String, ? extends Expression>>map(_expressions, _function);
final HashMap<String, Expression> paramMap = CollectionLiterals.<String, Expression>newHashMap(((Pair<? extends String, ? extends Expression>[])Conversions.unwrapArray(_map, Pair.class)));
final HashMap<String, Expression> exprMap = CollectionLiterals.<String, Expression>newHashMap(((Pair<? extends String, ? extends Expression>[])Conversions.unwrapArray(_map, Pair.class)));
EList<Parameter> _ownedParameters = op.getOwnedParameters();
final Function1<Parameter, Boolean> _function_1 = (Parameter it) -> {
ParameterDirectionKind _direction = it.getDirection();
return Boolean.valueOf((!Objects.equal(_direction, ParameterDirectionKind.RETURN_LITERAL)));
};
Iterable<Parameter> _filter = IterableExtensions.<Parameter>filter(_ownedParameters, _function_1);
final Consumer<Parameter> _function_2 = (Parameter it) -> {
final Function1<Parameter, Pair<String, Type>> _function_2 = (Parameter it) -> {
String _name = it.getName();
final Expression paramExpression = paramMap.get(_name);
Type _type = it.getType();
final IUMLTypeReference declaredType = this.typeFactory.typeReference(_type);
/* G |- paramExpression |> declaredType */
assignableInternal(G, _trace_, paramExpression, declaredType);
return Pair.<String, Type>of(_name, _type);
};
_filter.forEach(_function_2);
Iterable<Pair<? extends String, ? extends Type>> _map_1 = IterableExtensions.<Parameter, Pair<? extends String, ? extends Type>>map(_filter, _function_2);
final HashMap<String, Type> paramMap = CollectionLiterals.<String, Type>newHashMap(((Pair<? extends String, ? extends Type>[])Conversions.unwrapArray(_map_1, Pair.class)));
final Function2<String, Expression, Boolean> _function_3 = (String name, Expression expr) -> {
boolean _xblockexpression = false;
{
final Type declaredType = paramMap.get(name);
boolean _or = false;
boolean _or_1 = false;
boolean _equals = Objects.equal(expr, null);
if (_equals) {
_or_1 = true;
} else {
boolean _equals_1 = Objects.equal(declaredType, null);
_or_1 = _equals_1;
}
if (_or_1) {
_or = true;
} else {
/* G |- expr |> declaredType.typeReference */
IUMLTypeReference _typeReference = this.typeFactory.typeReference(declaredType);
boolean _ruleinvocation = assignableSucceeded(G, _trace_, expr, _typeReference);
boolean _not = (!_ruleinvocation);
_or = _not;
}
_xblockexpression = _or;
}
return Boolean.valueOf(_xblockexpression);
};
final Map<String, Expression> problematicValues = MapExtensions.<String, Expression>filter(exprMap, _function_3);
final Function2<String, Type, Boolean> _function_4 = (String name, Type declaredType) -> {
boolean _xblockexpression = false;
{
final Expression expr = exprMap.get(name);
boolean _or = false;
boolean _or_1 = false;
boolean _equals = Objects.equal(declaredType, null);
if (_equals) {
_or_1 = true;
} else {
boolean _equals_1 = Objects.equal(expr, null);
_or_1 = _equals_1;
}
if (_or_1) {
_or = true;
} else {
/* G |- expr |> declaredType.typeReference */
IUMLTypeReference _typeReference = this.typeFactory.typeReference(declaredType);
boolean _ruleinvocation = assignableSucceeded(G, _trace_, expr, _typeReference);
boolean _not = (!_ruleinvocation);
_or = _not;
}
_xblockexpression = _or;
}
return Boolean.valueOf(_xblockexpression);
};
final Map<String, Type> problematicDeclarations = MapExtensions.<String, Type>filter(paramMap, _function_4);
int _size = problematicValues.size();
boolean _greaterThan = (_size > 0);
if (_greaterThan) {
/* fail */
throwForExplicitFail();
}
int _size_1 = problematicDeclarations.size();
boolean _greaterThan_1 = (_size_1 > 0);
if (_greaterThan_1) {
/* fail */
throwForExplicitFail();
}
return new Result<Boolean>(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.incquerylabs.uml.ralf.reducedAlfLanguage.LocalNameDeclarationStatement;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.ReturnStatement;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SendSignalStatement;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.StaticFeatureInvocationExpression;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.SwitchStatement;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.Variable;
import com.incquerylabs.uml.ralf.reducedAlfLanguage.WhileStatement;
Expand Down Expand Up @@ -113,4 +114,11 @@ public void operationParameters(final FeatureInvocationExpression ex) {
getXsemanticsSystem().operationParameters(ex),
ex);
}

@Check
public void staticOperationParameters(final StaticFeatureInvocationExpression ex) {
errorGenerator.generateErrors(this,
getXsemanticsSystem().staticOperationParameters(ex),
ex);
}
}

0 comments on commit 436c6c1

Please sign in to comment.