/// <summary> /// Creates a new instance /// </summary> public RelationCallExpReferencedElementsCollection(RelationCallExp parent) { this._parent = parent; }
private EssentialOCL.IOclExpression ConstructOCLExpression(QVTRelations.IRelation relation, ExpressionSyntax parsedExpression, QVTBase.IPattern pattern, EMOF.IType type = null) { // Case single identifier => OCL VariableExp if (parsedExpression is IdentifierNameSyntax) { EssentialOCL.IVariable variable = ConstructVariable(relation, parsedExpression.ToString(), type); pattern?.BindsTo.Add(variable); return(new EssentialOCL.VariableExp() { ReferredVariable = variable }); } // Case method call => QVT RelationCallExp (if the relation exists) of function call (if the function exists) if (parsedExpression is InvocationExpressionSyntax) { InvocationExpressionSyntax invocationExpressionSyntax = (InvocationExpressionSyntax)parsedExpression; // We are only interested in direct calls if (invocationExpressionSyntax.Expression is IdentifierNameSyntax) { IdentifierNameSyntax methodIdentifier = (IdentifierNameSyntax)invocationExpressionSyntax.Expression; ArgumentListSyntax argumentList = invocationExpressionSyntax.ArgumentList; QVTRelations.IRelation calledRelation = FindRelation((QVTRelations.IRelationalTransformation)(relation.Transformation), methodIdentifier.ToString()); QVTBase.IFunction calledFunction = FindFunction((QVTRelations.IRelationalTransformation)(relation.Transformation), methodIdentifier.ToString()); if (calledRelation != null) { QVTRelations.RelationCallExp call = new QVTRelations.RelationCallExp { ReferredRelation = calledRelation }; if (argumentList.Arguments.Count != calledRelation.Domain.Count) { throw new InvalidQVTRelationsModelException("Relation " + relation.Name + ": wrong number of arguments in relation call " + calledRelation.Name); } foreach (ArgumentSyntax argumentSyntax in argumentList.Arguments) { QVTRelations.IRelationDomain correspondingDomain = (QVTRelations.IRelationDomain)calledRelation.Domain[argumentList.Arguments.IndexOf(argumentSyntax)]; ExpressionSyntax argumentExpression = argumentSyntax.Expression; EssentialOCL.IOclExpression argumentOCLExpression = ConstructOCLExpression(relation, argumentExpression, pattern, correspondingDomain.RootVariable.Type); call.Argument.Add(argumentOCLExpression); } return(call); } else if (calledFunction != null) { string methodname = methodIdentifier.ToString(); EssentialOCL.IOperationCallExp call = new EssentialOCL.OperationCallExp() { Type = calledFunction.Type, ReferredOperation = calledFunction, Name = calledFunction.Name, }; foreach (ArgumentSyntax argumentSyntax in argumentList.Arguments) { ExpressionSyntax argumentExpression = argumentSyntax.Expression; EssentialOCL.IOclExpression argumentOCLExpression = ConstructOCLExpression(relation, argumentExpression, pattern, calledFunction.Type); call.Argument.Add(argumentOCLExpression); } return(call); } } } // Case assignment => Custom Assignment //TODO replace by OCL '=='? Meaning having to provide basic parts of OCL standard lib if (parsedExpression is AssignmentExpressionSyntax) { AssignmentExpressionSyntax assignmentExpressionSyntax = (AssignmentExpressionSyntax)parsedExpression; IdentifierNameSyntax leftIdentifier = (IdentifierNameSyntax)assignmentExpressionSyntax.Left; ExpressionSyntax right = assignmentExpressionSyntax.Right; EssentialOCL.IVariable variable = ConstructVariable(relation, leftIdentifier.ToString()); pattern?.BindsTo.Add(variable); return(new EssentialOCL.Assignment() { AssignedVariable = variable, Value = ConstructOCLExpression(relation, right, pattern) }); } // Any other case => Custom CSharpOpaqueExpression // TODO replace by QVT "Function" with a black box implementation? EssentialOCL.CSharpOpaqueExpression cSharpOpaqueExpression = new EssentialOCL.CSharpOpaqueExpression() { Code = parsedExpression.ToString() }; SetBindings(relation, pattern, cSharpOpaqueExpression, parsedExpression); return(cSharpOpaqueExpression); }
/// <summary> /// Creates a new instance /// </summary> public RelationCallExpChildrenCollection(RelationCallExp parent) { this._parent = parent; }