public static bool IsValidSourceDomain(IRelationDomain domain) { ISet <IVariable> bindedVariables = new HashSet <IVariable>(); ISet <IVariable> variables = QvtModelExplorer.FindAllVariables(domain, bindedVariables); // The domain is valid if all variables are directly binded in the pattern return(variables.All(v => bindedVariables.Contains(v))); }
public static string GenerateConstructTarget(IRelationDomain targetDomain, bool useMetamodelInterface) { StringBuilder stringBuilder = new StringBuilder(); ISet <string> postPonedSets = new HashSet <string>(); List <IObjectTemplateExp> objectTemplates = QvtModelExplorer.FindAllObjectTemplates(targetDomain).Where(o => !o.IsAntiTemplate()).ToList(); foreach (IObjectTemplateExp objectTemplate in objectTemplates) { IVariable variable = objectTemplate.BindsTo; stringBuilder.AppendLine("\n// Contructing " + variable.Name); foreach (IPropertyTemplateItem propertyTemplateItem in objectTemplate.Part) { string setStatement = GenerateSetValue(propertyTemplateItem, variable.Name, (IRelation)targetDomain.Rule, useMetamodelInterface); IVariableExp targetVariableValue = propertyTemplateItem.Value as IVariableExp; IObjectTemplateExp targetObjTemplateValue = objectTemplates.FirstOrDefault(o => o.BindsTo == targetVariableValue?.ReferredVariable); bool ok = targetObjTemplateValue == null || objectTemplates.IndexOf(targetObjTemplateValue) < objectTemplates.IndexOf(objectTemplate); if (ok) { stringBuilder.AppendLine(setStatement); } else { postPonedSets.Add(setStatement); } } } if (!postPonedSets.IsNullOrEmpty()) { stringBuilder.AppendLine("// Setting cycling properties"); foreach (string setStatement in postPonedSets) { stringBuilder.AppendLine(setStatement); } } return(stringBuilder.ToString()); }
public static string GenerateDomainCheckMethodContent(IRelationDomain sourceDomain, ISet <IVariable> variablesBindedSoFar, DomainVariablesBindingsResult analysis, List <IObjectTemplateExp> remaining = null, StringBuilder stringBuilder = null, ISet <IPropertyTemplateItem> postPonedPropertiesToCheck = null) { if (remaining == null) { remaining = QvtModelExplorer.FindAllObjectTemplates(sourceDomain).Where(o => !o.IsAntiTemplate()).ToList(); } if (stringBuilder == null) { stringBuilder = new StringBuilder(); } if (postPonedPropertiesToCheck == null) { postPonedPropertiesToCheck = new HashSet <IPropertyTemplateItem>(); } if (remaining.Count > 0) { IObjectTemplateExp current = remaining[0]; remaining.RemoveAt(0); string currentVariableName = current.BindsTo.Name; variablesBindedSoFar.Add(current.BindsTo); // Generate conditional for the object template stringBuilder.AppendLine("if (" + currentVariableName + " != null) {"); // Generate bindings for each non-many free variables ISet <IPropertyTemplateItem> managedProps = new HashSet <IPropertyTemplateItem>(); foreach (IPropertyTemplateItem nonManyProp in current.Part.Where(prop => (prop.Value is ObjectTemplateExp || prop.Value is VariableExp) && !prop.ReferredProperty.isMany())) { IVariable bindedVariable = QvtModelExplorer.FindBindedVariables(nonManyProp).Single(); if (bindedVariable != null && !variablesBindedSoFar.Contains(bindedVariable)) { managedProps.Add(nonManyProp); stringBuilder.AppendLine(GenerateBindingFreeNonMany(nonManyProp, bindedVariable)); variablesBindedSoFar.Add(bindedVariable); } } // We compute the checks that we can do right now, and the ones that must be post poned because their variables are not binded yet // For now we only do checks on single value properties, the many valued one are simply exhaustively explored/binded later IEnumerable <IPropertyTemplateItem> candidatesInit = current.Part.Where(prop => !prop.ReferredProperty.isMany() && (prop.Value is CSharpOpaqueExpression || prop.Value is IVariableExp)); ISet <IPropertyTemplateItem> candidates = new HashSet <IPropertyTemplateItem>(); candidates.UnionWith(candidatesInit); candidates.UnionWith(postPonedPropertiesToCheck); candidates.ExceptWith(managedProps); ISet <IPropertyTemplateItem> propsToCheck = new HashSet <IPropertyTemplateItem>(); foreach (IPropertyTemplateItem candidate in candidates) { if (!variablesBindedSoFar.IsSupersetOf(QvtModelExplorer.FindBindedVariables(candidate))) { propsToCheck.Remove(candidate); postPonedPropertiesToCheck.Add(candidate); } else { propsToCheck.Add(candidate); postPonedPropertiesToCheck.Remove(candidate); } } // We generate the checks for all the ones that can be made now if (propsToCheck.Count > 0) { IEnumerable <string> conditions = propsToCheck.Select(u => GenerateConditionnalProperty(u, true)); string condition = string.Join(" && ", conditions); stringBuilder.AppendLine("if (" + condition + ") {"); } // We make a recursion for each object template not managed yet // - If the ref is many, then we make the binding first using a loop // - If the ref is not many, the binding was done before when managing non-many List <IPropertyTemplateItem> objectTemplatesManyRemaining = current.Part.Where(p => p.Value is ObjectTemplateExp && p.ReferredProperty.isMany() && remaining.Contains(p.Value)).ToList(); foreach (IPropertyTemplateItem propWithTemplate in objectTemplatesManyRemaining) { // Generate start for each, which binds the variable associated with the object template ObjectTemplateExp objectTemplate = (ObjectTemplateExp)propWithTemplate.Value; stringBuilder.AppendLine("foreach (" + objectTemplate.BindsTo.Type.GetRealTypeName() + " " + objectTemplate.BindsTo.Name + " in " + currentVariableName + "." + propWithTemplate.ReferredProperty.Name + ".OfType<" + propWithTemplate.ReferredProperty.Type.GetRealTypeName() + ">()) {"); variablesBindedSoFar.Add(objectTemplate.BindsTo); } GenerateDomainCheckMethodContent(sourceDomain, variablesBindedSoFar, analysis, remaining, stringBuilder, postPonedPropertiesToCheck); foreach (IPropertyTemplateItem _ in objectTemplatesManyRemaining) { // Generate end for each stringBuilder.AppendLine("}"); } // Generate end if checks all c# expressions if (propsToCheck.Count > 0) { stringBuilder.Append("}"); } // End conditional on the object template stringBuilder.AppendLine("}"); } // We stop the recursion if there are no more object templates to manage else { string matchClassName = QvtCodeGeneratorStrings.MatchDomainClassName(sourceDomain); // Now we can finally create the Match object stringBuilder.AppendLine(matchClassName + " match = new " + matchClassName + "() {"); foreach (IVariable variable in analysis.VariablesItCanBind) { stringBuilder.AppendLine(variable.Name + " = " + variable.Name + ","); } stringBuilder.AppendLine("};"); stringBuilder.AppendLine("result.Add(match);"); } return(stringBuilder.ToString()); }