private QVTTemplate.IPropertyTemplateItem ConstructPropertyTemplateItem(QVTRelations.IRelation relation, QVTRelations.IDomainPattern domainPattern, QVTTemplate.IObjectTemplateExp objectTemplateExp, RunStateField runStateField) { ISet <EMOF.IProperty> atts = objectTemplateExp.ReferredClass.GetAllInheritedAttributes(); EMOF.IProperty property = atts.Single(p => string.Equals(p.Name, runStateField.Variable, StringComparison.CurrentCultureIgnoreCase)); QVTTemplate.IPropertyTemplateItem propertyTemplateItem = null; if (property != null) { EssentialOCL.IOclExpression expression = ConstructOCLExpression(relation, runStateField.Value, domainPattern, property.Type); propertyTemplateItem = new QVTTemplate.PropertyTemplateItem() { ReferredProperty = property, Value = expression, IsOpposite = false, // TODO? ObjContainer = objectTemplateExp }; } return(propertyTemplateItem); }
private QVTBase.IPattern ConstructWhenOrWherePattern(QVTRelations.IRelation relation, string whenOrwhereCode) { QVTBase.Pattern result = new QVTBase.Pattern(); List <StatementSyntax> instructions = CSharpParser.ParseInstructions(whenOrwhereCode); //TODO Filter ExpressionStatementSyntax is too restrictive, we must also create opaque expressions with eg. conditionnals foreach (ExpressionStatementSyntax expressionStatementSyntax in instructions.OfType <ExpressionStatementSyntax>()) { ExpressionSyntax expression = expressionStatementSyntax.Expression; EssentialOCL.IOclExpression oclExpression = ConstructOCLExpression(relation, expression, result); QVTBase.IPredicate predicate = new QVTBase.Predicate() { Pattern = result, ConditionExpression = oclExpression, }; result.Predicate.Add(predicate); } return(result); }
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); }