diff --git a/plugins/com.incquerylabs.emdw.umlintegration.queries/src/com/incquerylabs/emdw/umlintegration/queries/UMLScopeQueries.eiq b/plugins/com.incquerylabs.emdw.umlintegration.queries/src/com/incquerylabs/emdw/umlintegration/queries/UMLScopeQueries.eiq index 2576067..35bc442 100644 --- a/plugins/com.incquerylabs.emdw.umlintegration.queries/src/com/incquerylabs/emdw/umlintegration/queries/UMLScopeQueries.eiq +++ b/plugins/com.incquerylabs.emdw.umlintegration.queries/src/com/incquerylabs/emdw/umlintegration/queries/UMLScopeQueries.eiq @@ -73,6 +73,11 @@ pattern operationsOfClass(cl : Classifier, op : Operation) { DataType.ownedOperation(sup, op); } +pattern operationsOfClassByName(cl : Classifier, op : Operation, name) { + find operationsOfClass(cl, op); + Operation.name(op, name); +} + pattern staticOperations(op : Operation) { find operation(_, op); Operation.isStatic(op, true); diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageRuntimeModule.java b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageRuntimeModule.java index 8031e59..338ec5a 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageRuntimeModule.java +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageRuntimeModule.java @@ -4,11 +4,13 @@ package com.incquerylabs.uml.ralf; import org.eclipse.xtext.conversion.IValueConverterService; +import org.eclipse.xtext.linking.ILinkingService; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; import org.eclipse.xtext.resource.XtextResource; import com.incquerylabs.uml.ralf.resource.ReducedAlfLanguageResource; +import com.incquerylabs.uml.ralf.scoping.ReducedAlfLanguageLinkingService; import com.incquerylabs.uml.ralf.scoping.ReducedAlfLanguageQualifiedNameConverter; import com.incquerylabs.uml.ralf.scoping.ReducedAlfLanguageResourceDescriptionStrategy; @@ -34,6 +36,10 @@ public Class bindIQualifiedNameConverter() { public Class bindXtextResource() { return ReducedAlfLanguageResource.class; } - + + @Override + public Class bindILinkingService() { + return ReducedAlfLanguageLinkingService.class; + } } diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageSemantics.xsemantics b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageSemantics.xsemantics index d033af9..98b8815 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageSemantics.xsemantics +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/ReducedAlfLanguageSemantics.xsemantics @@ -73,6 +73,7 @@ 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 @@ -91,6 +92,7 @@ judgments { type |- EObject expression : output IUMLTypeReference error "Cannot type " + stringRep(expression) source expression + operationParametersType |- Operation op <: Tuple params operationType |- Operation op <: Tuple params :> output IUMLTypeReference error "Invalid parameter types " + stringRep(op) source op @@ -277,30 +279,42 @@ from { /** * Operation typing */ -rule OperationTyping - G |- Operation op <: Tuple params :> IUMLTypeReference result +rule OperationTypingWith + G |- Operation op <: Tuple params from { fail } +rule OperationTypingWithResult + G |- Operation op <: Tuple params :> IUMLTypeReference result +from { + G |- op <: params + G |- op : result +} rule ParameterListTyping - G |- Operation op <: ExpressionList params :> IUMLTypeReference result + G |- Operation op <: ExpressionList params from { - val opParamLength = op.ownedParameters.size + val declaredParameters = op.ownedParameters.filter[direction != ParameterDirectionKind.RETURN_LITERAL] + + val opParamLength = declaredParameters.size val paramLength = params.expressions.size opParamLength == paramLength for (var i = 0; i < paramLength; i++) { - val declaredType = op.ownedParameters.get(i).type.typeReference + val declaredType = declaredParameters.get(i).type.typeReference G |- params.expressions.get(i) |> declaredType } - - G |- op : result } + rule NamedTupleTyping - G |- Operation op <: NamedTuple params :> IUMLTypeReference result -from { - - result = op.returnParameter.type.typeReference + G |- Operation op <: NamedTuple params +from { + val paramMap = 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 + ] } /** diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/resource/ReducedAlfLanguageResource.java b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/resource/ReducedAlfLanguageResource.java index de549a3..975edaf 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/resource/ReducedAlfLanguageResource.java +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/resource/ReducedAlfLanguageResource.java @@ -1,6 +1,14 @@ package com.incquerylabs.uml.ralf.resource; +import java.util.List; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.xtext.diagnostics.DiagnosticMessage; +import org.eclipse.xtext.diagnostics.Severity; import org.eclipse.xtext.linking.lazy.LazyLinkingResource; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.util.Triple; import com.google.inject.Inject; import com.incquerylabs.uml.ralf.scoping.IUMLContextProvider; @@ -13,4 +21,39 @@ public class ReducedAlfLanguageResource extends LazyLinkingResource { public IUMLContextProvider getUmlContextProvider() { return umlContextProvider; } + + @Override + protected EObject getEObject(String uriFragment, Triple triple) throws AssertionError { + try { + return super.getEObject(uriFragment, triple); + } catch (IllegalStateException e) { + if (e.getMessage().startsWith("linkingService returned more than one object for fragment ")) { + List linkedObjects = getLinkingService().getLinkedObjects( + triple.getFirst(), + triple.getSecond(), + triple.getThird()); + createAndAddDiagnostic(triple, linkedObjects); + return null; + } else { + throw e; + } + } + } + + protected void createAndAddDiagnostic(Triple triple, List linkedObjects) { + if (isValidationDisabled()) + return; + + String messageText = "Cannot select between multiple linking candidates"; + + DiagnosticMessage message = new DiagnosticMessage(messageText, Severity.ERROR, org.eclipse.xtext.diagnostics.Diagnostic.LINKING_DIAGNOSTIC); + + if (message != null) { + List list = getDiagnosticList(message); + Diagnostic diagnostic = createDiagnostic(triple, message); + if (!list.contains(diagnostic)) + list.add(diagnostic); + } + } + } diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/IUMLContextProvider.java b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/IUMLContextProvider.java index bcfc0b3..05fc224 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/IUMLContextProvider.java +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/IUMLContextProvider.java @@ -35,6 +35,7 @@ public interface IUMLContextProvider { Iterable getPropertiesOfClass(Classifier cl); Iterable getAssociationsOfClass(Classifier cl); Iterable getOperationsOfClass(Classifier cl); + Set getOperationCandidatesOfClass(Classifier cl, String name); Iterable getStaticOperations(); /** diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/ReducedAlfLanguageLinkingService.java b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/ReducedAlfLanguageLinkingService.java new file mode 100644 index 0000000..9fe01e4 --- /dev/null +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/ReducedAlfLanguageLinkingService.java @@ -0,0 +1,113 @@ +package com.incquerylabs.uml.ralf.scoping; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +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.Type; +import org.eclipse.xtext.linking.impl.DefaultLinkingService; +import org.eclipse.xtext.linking.impl.IllegalNodeException; +import org.eclipse.xtext.nodemodel.INode; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.inject.Inject; +import com.incquerylabs.uml.ralf.ReducedAlfSystem; +import com.incquerylabs.uml.ralf.reducedAlfLanguage.Expression; +import com.incquerylabs.uml.ralf.reducedAlfLanguage.FeatureInvocationExpression; +import com.incquerylabs.uml.ralf.reducedAlfLanguage.Tuple; +import com.incquerylabs.uml.ralf.resource.ReducedAlfLanguageResource; + +import it.xsemantics.runtime.Result; + +public class ReducedAlfLanguageLinkingService extends DefaultLinkingService { + + + private boolean parametersMatch(List parameters, List otherParameters) { + if (parameters.size() != otherParameters.size()) { + return false; + } + for (int i = 0; i < parameters.size(); i++) { + Parameter param = parameters.get(i); + Parameter otherParam = otherParameters.get(i); + if (param.getDirection() != otherParam.getDirection() || + param.getType().conformsTo(otherParam.getType())) { + return false; + } + } + return true; + } + + private boolean operationRedefines(Operation op, Operation redefinedOp) { + if (op.getRedefinedOperations().contains(redefinedOp)) { + return true; + } + Class opClass = op.getClass_(); + Class redefinedClass = redefinedOp.getClass_(); + if (!opClass.allParents().contains(redefinedClass)) { + return false; + } + return parametersMatch(op.getOwnedParameters(), redefinedOp.getOwnedParameters()); + } + + private boolean operationMatchesParameters(Operation op, Tuple parameters) { + Result result = typeSystem.operationParametersType(op, parameters); + return !result.failed(); + } + + @Inject + ReducedAlfSystem typeSystem; + + @Override + public List getLinkedObjects(EObject context, EReference ref, INode node) throws IllegalNodeException { + List linkedObjects = super.getLinkedObjects(context, ref, node); + //If the linked object is an operation, search for possible alternates + if (linkedObjects.size() == 1 && linkedObjects.get(0) instanceof Operation) { + Operation op = (Operation) linkedObjects.get(0); + IUMLContextProvider umlContext = ((ReducedAlfLanguageResource)context.eResource()).getUmlContextProvider(); + Expression ctx = null; + Tuple parameters = null; + if (context instanceof FeatureInvocationExpression) { + FeatureInvocationExpression featureInvocationExpression = (FeatureInvocationExpression) context; + ctx = featureInvocationExpression.getContext(); + parameters = featureInvocationExpression.getParameters(); + } + Type contextType = typeSystem.type(ctx).getValue().getUmlType(); + Set candidates = umlContext.getOperationCandidatesOfClass((Classifier) contextType, op.getName()); + if (candidates.size() > 1) { + linkedObjects = calculateBestCandidates(candidates, parameters); + } + } + return linkedObjects; + } + + private List calculateBestCandidates(Set candidates, Tuple parameters) { + Set remainingCandidates = Sets.newHashSet(candidates); + + for (Operation op : candidates) { + Iterator it = remainingCandidates.iterator(); + while (it.hasNext()) { + Operation next = it.next(); + if (operationRedefines(op, next)) { + it.remove(); + } + } + } + + Iterator it = remainingCandidates.iterator(); + while(it.hasNext()) { + Operation next = it.next(); + if (!operationMatchesParameters(next, parameters)) { + it.remove(); + } + } + + return Lists.newArrayList(remainingCandidates); + } +} diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/SimpleUMLContextProvider.xtend b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/SimpleUMLContextProvider.xtend index eed2d93..8473eb6 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/SimpleUMLContextProvider.xtend +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/SimpleUMLContextProvider.xtend @@ -74,4 +74,9 @@ class SimpleUMLContextProvider extends AbstractUMLContextProvider { null } + override getOperationCandidatesOfClass(Classifier cl, String name) { + newHashSet() + } + + } \ No newline at end of file diff --git a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/UMLContextProvider.java b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/UMLContextProvider.java index 338b984..7cd28e1 100644 --- a/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/UMLContextProvider.java +++ b/plugins/com.incquerylabs.uml.ralf/src/com/incquerylabs/uml/ralf/scoping/UMLContextProvider.java @@ -36,6 +36,7 @@ import com.incquerylabs.emdw.umlintegration.queries.AssociationsOfClassifierMatcher; import com.incquerylabs.emdw.umlintegration.queries.AttributesOfClassifierMatcher; import com.incquerylabs.emdw.umlintegration.queries.CommonAncestorSignalMatcher; +import com.incquerylabs.emdw.umlintegration.queries.OperationsOfClassByNameMatcher; import com.incquerylabs.emdw.umlintegration.queries.OperationsOfClassMatcher; import com.incquerylabs.emdw.umlintegration.queries.SignalsMatcher; import com.incquerylabs.emdw.umlintegration.queries.StaticOperationsMatcher; @@ -58,6 +59,7 @@ protected IncQueryEngine getEngine() throws IncQueryException, IncQueryBaseExcep SignalsMatcher.querySpecification(), UmlTypesMatcher.querySpecification(), OperationsOfClassMatcher.querySpecification(), + OperationsOfClassByNameMatcher.querySpecification(), StaticOperationsMatcher.querySpecification(), TriggerSignalOfBehaviorMatcher.querySpecification(), CommonAncestorSignalMatcher.querySpecification() @@ -181,6 +183,18 @@ public Set getOperationsOfClass(Classifier cl, final boolean staticCl return Sets.newHashSet(); } + @Override + public Set getOperationCandidatesOfClass(Classifier cl, String name) { + try { + OperationsOfClassByNameMatcher matcher = OperationsOfClassByNameMatcher.on(getEngine()); + return matcher.getAllValuesOfop(cl, name); + } catch (IncQueryException | IncQueryBaseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return Sets.newHashSet(); + } + @Override public Signal getIncomingSignalType() { try { diff --git a/plugins/com.incquerylabs.uml.ralf/xsemantics-gen/com/incquerylabs/uml/ralf/ReducedAlfSystem.java b/plugins/com.incquerylabs.uml.ralf/xsemantics-gen/com/incquerylabs/uml/ralf/ReducedAlfSystem.java index d922542..f9b5eca 100644 --- a/plugins/com.incquerylabs.uml.ralf/xsemantics-gen/com/incquerylabs/uml/ralf/ReducedAlfSystem.java +++ b/plugins/com.incquerylabs.uml.ralf/xsemantics-gen/com/incquerylabs/uml/ralf/ReducedAlfSystem.java @@ -33,6 +33,7 @@ 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.NamedExpression; import com.incquerylabs.uml.ralf.reducedAlfLanguage.NamedTuple; import com.incquerylabs.uml.ralf.reducedAlfLanguage.NaturalLiteralExpression; import com.incquerylabs.uml.ralf.reducedAlfLanguage.NullExpression; @@ -68,7 +69,9 @@ import it.xsemantics.runtime.RuleEnvironment; import it.xsemantics.runtime.RuleFailedException; import it.xsemantics.runtime.XsemanticsRuntimeSystem; +import java.util.HashMap; import java.util.List; +import java.util.function.Consumer; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.uml2.uml.Association; @@ -77,12 +80,19 @@ import org.eclipse.uml2.uml.NamedElement; 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 org.eclipse.xtext.util.PolymorphicDispatcher; +import org.eclipse.xtext.xbase.lib.CollectionLiterals; +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.IterableExtensions; +import org.eclipse.xtext.xbase.lib.ListExtensions; +import org.eclipse.xtext.xbase.lib.Pair; @SuppressWarnings("all") public class ReducedAlfSystem extends XsemanticsRuntimeSystem { @@ -134,7 +144,9 @@ public class ReducedAlfSystem extends XsemanticsRuntimeSystem { public final static String EXPRESSIONASSIGNABLETOTYPE = "com.incquerylabs.uml.ralf.ExpressionAssignableToType"; - public final static String OPERATIONTYPING = "com.incquerylabs.uml.ralf.OperationTyping"; + public final static String OPERATIONTYPINGWITH = "com.incquerylabs.uml.ralf.OperationTypingWith"; + + public final static String OPERATIONTYPINGWITHRESULT = "com.incquerylabs.uml.ralf.OperationTypingWithResult"; public final static String PARAMETERLISTTYPING = "com.incquerylabs.uml.ralf.ParameterListTyping"; @@ -216,6 +228,8 @@ public class ReducedAlfSystem extends XsemanticsRuntimeSystem { private PolymorphicDispatcher> typeDispatcher; + private PolymorphicDispatcher> operationParametersTypeDispatcher; + private PolymorphicDispatcher> operationTypeDispatcher; private PolymorphicDispatcher> subtypeReferenceDispatcher; @@ -231,6 +245,8 @@ public ReducedAlfSystem() { public void init() { typeDispatcher = buildPolymorphicDispatcher1( "typeImpl", 3, "|-", ":"); + operationParametersTypeDispatcher = buildPolymorphicDispatcher1( + "operationParametersTypeImpl", 4, "|-", "<:"); operationTypeDispatcher = buildPolymorphicDispatcher1( "operationTypeImpl", 4, "|-", "<:", ":>"); subtypeReferenceDispatcher = buildPolymorphicDispatcher1( @@ -317,6 +333,39 @@ public Result type(final RuleEnvironment _environment_, final } } + public Result operationParametersType(final Operation op, final Tuple params) { + return operationParametersType(new RuleEnvironment(), null, op, params); + } + + public Result operationParametersType(final RuleEnvironment _environment_, final Operation op, final Tuple params) { + return operationParametersType(_environment_, null, op, params); + } + + public Result operationParametersType(final RuleEnvironment _environment_, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) { + try { + return operationParametersTypeInternal(_environment_, _trace_, op, params); + } catch (Exception _e_operationParametersType) { + return resultForFailure(_e_operationParametersType); + } + } + + public Boolean operationParametersTypeSucceeded(final Operation op, final Tuple params) { + return operationParametersTypeSucceeded(new RuleEnvironment(), null, op, params); + } + + public Boolean operationParametersTypeSucceeded(final RuleEnvironment _environment_, final Operation op, final Tuple params) { + return operationParametersTypeSucceeded(_environment_, null, op, params); + } + + public Boolean operationParametersTypeSucceeded(final RuleEnvironment _environment_, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) { + try { + operationParametersTypeInternal(_environment_, _trace_, op, params); + return true; + } catch (Exception _e_operationParametersType) { + return false; + } + } + public Result operationType(final Operation op, final Tuple params) { return operationType(new RuleEnvironment(), null, op, params); } @@ -926,6 +975,20 @@ protected void typeThrowException(final String _error, final String _issue, fina _issue, _ex, new ErrorInformation(source, null)); } + protected Result operationParametersTypeInternal(final RuleEnvironment _environment_, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) { + try { + checkParamsNotNull(op, params); + return operationParametersTypeDispatcher.invoke(_environment_, _trace_, op, params); + } catch (Exception _e_operationParametersType) { + sneakyThrowRuleFailedException(_e_operationParametersType); + return null; + } + } + + protected void operationParametersTypeThrowException(final String _error, final String _issue, final Exception _ex, final Operation op, final Tuple params, final ErrorInformation[] _errorInformations) throws RuleFailedException { + throwRuleFailedException(_error, _issue, _ex, _errorInformations); + } + protected Result operationTypeInternal(final RuleEnvironment _environment_, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) { try { checkParamsNotNull(op, params); @@ -1844,55 +1907,89 @@ protected Result applyRuleExpressionAssignableToType(final RuleEnvironm return new Result(true); } - protected Result operationTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { + protected Result operationParametersTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { try { final RuleApplicationTrace _subtrace_ = newTrace(_trace_); - final Result _result_ = applyRuleOperationTyping(G, _subtrace_, op, params); + final Result _result_ = applyRuleOperationTypingWith(G, _subtrace_, op, params); addToTrace(_trace_, new Provider() { public Object get() { - return ruleName("OperationTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + stringRep(_result_.getFirst()); + return ruleName("OperationTypingWith") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params); } }); addAsSubtrace(_trace_, _subtrace_); return _result_; - } catch (Exception e_applyRuleOperationTyping) { - operationTypeThrowException(ruleName("OperationTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + "IUMLTypeReference", - OPERATIONTYPING, - e_applyRuleOperationTyping, op, params, new ErrorInformation[] {new ErrorInformation(op), new ErrorInformation(params)}); + } catch (Exception e_applyRuleOperationTypingWith) { + operationParametersTypeThrowException(ruleName("OperationTypingWith") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params), + OPERATIONTYPINGWITH, + e_applyRuleOperationTypingWith, op, params, new ErrorInformation[] {new ErrorInformation(op), new ErrorInformation(params)}); return null; } } - protected Result applyRuleOperationTyping(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { - IUMLTypeReference result = null; // output parameter + protected Result applyRuleOperationTypingWith(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { /* fail */ throwForExplicitFail(); + return new Result(true); + } + + protected Result operationTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { + try { + final RuleApplicationTrace _subtrace_ = newTrace(_trace_); + final Result _result_ = applyRuleOperationTypingWithResult(G, _subtrace_, op, params); + addToTrace(_trace_, new Provider() { + public Object get() { + return ruleName("OperationTypingWithResult") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + stringRep(_result_.getFirst()); + } + }); + addAsSubtrace(_trace_, _subtrace_); + return _result_; + } catch (Exception e_applyRuleOperationTypingWithResult) { + operationTypeThrowException(ruleName("OperationTypingWithResult") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + "IUMLTypeReference", + OPERATIONTYPINGWITHRESULT, + e_applyRuleOperationTypingWithResult, op, params, new ErrorInformation[] {new ErrorInformation(op), new ErrorInformation(params)}); + return null; + } + } + + protected Result applyRuleOperationTypingWithResult(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final Tuple params) throws RuleFailedException { + IUMLTypeReference result = null; // output parameter + /* G |- op <: params */ + operationParametersTypeInternal(G, _trace_, op, params); + /* G |- op : result */ + Result result_1 = typeInternal(G, _trace_, op); + checkAssignableTo(result_1.getFirst(), IUMLTypeReference.class); + result = (IUMLTypeReference) result_1.getFirst(); + return new Result(result); } - protected Result operationTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final ExpressionList params) throws RuleFailedException { + protected Result operationParametersTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final ExpressionList params) throws RuleFailedException { try { final RuleApplicationTrace _subtrace_ = newTrace(_trace_); - final Result _result_ = applyRuleParameterListTyping(G, _subtrace_, op, params); + final Result _result_ = applyRuleParameterListTyping(G, _subtrace_, op, params); addToTrace(_trace_, new Provider() { public Object get() { - return ruleName("ParameterListTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + stringRep(_result_.getFirst()); + return ruleName("ParameterListTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params); } }); addAsSubtrace(_trace_, _subtrace_); return _result_; } catch (Exception e_applyRuleParameterListTyping) { - operationTypeThrowException(ruleName("ParameterListTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + "IUMLTypeReference", + operationParametersTypeThrowException(ruleName("ParameterListTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params), PARAMETERLISTTYPING, e_applyRuleParameterListTyping, op, params, new ErrorInformation[] {new ErrorInformation(op), new ErrorInformation(params)}); return null; } } - protected Result applyRuleParameterListTyping(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final ExpressionList params) throws RuleFailedException { - IUMLTypeReference result = null; // output parameter + protected Result applyRuleParameterListTyping(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final ExpressionList params) throws RuleFailedException { EList _ownedParameters = op.getOwnedParameters(); - final int opParamLength = _ownedParameters.size(); + final Function1 _function = (Parameter it) -> { + ParameterDirectionKind _direction = it.getDirection(); + return Boolean.valueOf((!Objects.equal(_direction, ParameterDirectionKind.RETURN_LITERAL))); + }; + final Iterable declaredParameters = IterableExtensions.filter(_ownedParameters, _function); + final int opParamLength = IterableExtensions.size(declaredParameters); EList _expressions = params.getExpressions(); final int paramLength = _expressions.size(); /* opParamLength == paramLength */ @@ -1900,8 +1997,7 @@ protected Result applyRuleParameterListTyping(final RuleEnvir sneakyThrowRuleFailedException("opParamLength == paramLength"); } for (int i = 0; (i < paramLength); i++) { - EList _ownedParameters_1 = op.getOwnedParameters(); - Parameter _get = _ownedParameters_1.get(i); + Parameter _get = ((Parameter[])Conversions.unwrapArray(declaredParameters, Parameter.class))[i]; Type _type = _get.getType(); final IUMLTypeReference declaredType = this.typeFactory.typeReference(_type); /* G |- params.expressions.get(i) |> declaredType */ @@ -1909,40 +2005,53 @@ protected Result applyRuleParameterListTyping(final RuleEnvir Expression _get_1 = _expressions_1.get(i); assignableInternal(G, _trace_, _get_1, declaredType); } - /* G |- op : result */ - Result result_1 = typeInternal(G, _trace_, op); - checkAssignableTo(result_1.getFirst(), IUMLTypeReference.class); - result = (IUMLTypeReference) result_1.getFirst(); - - return new Result(result); + return new Result(true); } - protected Result operationTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final NamedTuple params) throws RuleFailedException { + protected Result operationParametersTypeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final NamedTuple params) throws RuleFailedException { try { final RuleApplicationTrace _subtrace_ = newTrace(_trace_); - final Result _result_ = applyRuleNamedTupleTyping(G, _subtrace_, op, params); + final Result _result_ = applyRuleNamedTupleTyping(G, _subtrace_, op, params); addToTrace(_trace_, new Provider() { public Object get() { - return ruleName("NamedTupleTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + stringRep(_result_.getFirst()); + return ruleName("NamedTupleTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params); } }); addAsSubtrace(_trace_, _subtrace_); return _result_; } catch (Exception e_applyRuleNamedTupleTyping) { - operationTypeThrowException(ruleName("NamedTupleTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params) + " :> " + "IUMLTypeReference", + operationParametersTypeThrowException(ruleName("NamedTupleTyping") + stringRepForEnv(G) + " |- " + stringRep(op) + " <: " + stringRep(params), NAMEDTUPLETYPING, e_applyRuleNamedTupleTyping, op, params, new ErrorInformation[] {new ErrorInformation(op), new ErrorInformation(params)}); return null; } } - protected Result applyRuleNamedTupleTyping(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final NamedTuple params) throws RuleFailedException { - IUMLTypeReference result = null; // output parameter - Parameter _returnParameter = this.scopeHelper.getReturnParameter(op); - Type _type = _returnParameter.getType(); - IUMLTypeReference _typeReference = this.typeFactory.typeReference(_type); - result = _typeReference; - return new Result(result); + protected Result applyRuleNamedTupleTyping(final RuleEnvironment G, final RuleApplicationTrace _trace_, final Operation op, final NamedTuple params) throws RuleFailedException { + EList _expressions = params.getExpressions(); + final Function1> _function = (NamedExpression it) -> { + String _name = it.getName(); + Expression _expression = it.getExpression(); + return Pair.of(_name, _expression); + }; + List> _map = ListExtensions.>map(_expressions, _function); + final HashMap paramMap = CollectionLiterals.newHashMap(((Pair[])Conversions.unwrapArray(_map, Pair.class))); + EList _ownedParameters = op.getOwnedParameters(); + final Function1 _function_1 = (Parameter it) -> { + ParameterDirectionKind _direction = it.getDirection(); + return Boolean.valueOf((!Objects.equal(_direction, ParameterDirectionKind.RETURN_LITERAL))); + }; + Iterable _filter = IterableExtensions.filter(_ownedParameters, _function_1); + final Consumer _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); + }; + _filter.forEach(_function_2); + return new Result(true); } protected Result typeImpl(final RuleEnvironment G, final RuleApplicationTrace _trace_, final NumericUnaryExpression ex) throws RuleFailedException {