public static string GenerateExpression(IOclExpression expression, bool useMetamodelInterface)
 {
     if (expression is IOperationCallExp)
     {
         IOperationCallExp value = (IOperationCallExp)expression;
         return("transformation.Functions." + value.ReferredOperation.Name + "(" + string.Join(",", value.Argument.Select(u => GenerateExpression(u, useMetamodelInterface))) + ")");
     }
     if (expression is CSharpOpaqueExpression)
     {
         CSharpOpaqueExpression value = (CSharpOpaqueExpression)expression;
         return(value.Code);
     }
     if (expression is IVariableExp)
     {
         return(((IVariableExp)expression).ReferredVariable.Name);
     }
     if (expression is Assignment)
     {
         Assignment assignment = (Assignment)expression;
         return(assignment.AssignedVariable.Type.GetRealTypeName() + " " + assignment.AssignedVariable.Name + " = " + GenerateExpression(assignment.Value, useMetamodelInterface));
     }
     if (expression is IRelationCallExp)
     {
         IRelationCallExp relationCallExp = (IRelationCallExp)expression;
         return("transformation." + QvtCodeGeneratorStrings.RelationClassName(relationCallExp.ReferredRelation)
                + ".CheckAndEnforce(" + string.Join(",", relationCallExp.Argument.Select(u => GenerateExpression(u, useMetamodelInterface))) + ")");
     }
     throw new CodeGeneratorException("Cannot manage expression: " + expression);
 }
        private static string GenerateCheckAndAddDictionnary(IList <IList <IPropertyTemplateItem> > propertyPathsTransformationKey, string varName, IKey transformationKey)
        {
            StringBuilder  sb          = new StringBuilder();
            IList <string> tupleTypes  = propertyPathsTransformationKey.Select(pp => pp.Last().ReferredProperty.Type.GetRealTypeName()).Select(name => name + (cSharpPrimitiveTypes.Contains(name) ? "?" : "")).ToList();
            IList <string> tupleValues = propertyPathsTransformationKey.Select(pp => GenerateAccess(varName, pp)).ToList();

            string tupleTypesCombined  = string.Join(",", tupleTypes);
            string tupleValuesCombined = string.Join(",", tupleValues);

            string testDictionnary = "transformation."
                                     + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                     + ".ContainsKey(new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombined + "))";
            string accessDictionnaryWrite = "transformation."
                                            + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                            + "[new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombined + ")]";

            sb.AppendLine("if (" + testDictionnary + ") {");
            sb.AppendLine("throw new Exception(\"Two objects cannot have the same key\");");
            sb.AppendLine("} else {");
            sb.AppendLine(accessDictionnaryWrite + "=" + varName + ";");
            sb.AppendLine("}");
            return(sb.ToString());
        }
Exemplo n.º 3
0
        /// <summary>
        /// Create the template output
        /// </summary>
        public virtual string TransformText()
        {
            this.Write("\r\n");
            this.Write("\r\n");
            this.Write("\r\n\r\n\r\n");
            this.Write("\r\n\r\nusing System;\r\nusing System.Collections.Generic; \r\nusing System.Linq;\r\nusing " +
                       "LL.MDE.Components.Qvt.Common;\r\n");

            #line 23 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"

            // Small hack to bypass limitation of ForTea plugin ( https://github.com/MrJul/ForTea/issues/3 )
            // We redeclare members so that ForTea finds them, and enables code completion etc.
            // The errors can be ignored, as the generated .cs file compiles correctly.
            IRelationalTransformation transformation           = this.Transformation;
            ISet <ITypedModel>        validEnforceTargetParams = this.validEnforceTargetParams;
            bool useMetamodelInterface = this.useMetamodelInterface;


            #line default
            #line hidden
            this.Write("\r\n");

            #line 32 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            // Generating of the "usings", for each package of each metamodel used in the transformation
            foreach (IPackage package in transformation.ModelParameter.Select(p => p.UsedPackage).SelectMany(i => i).Distinct())
            {
            #line default
            #line hidden
                this.Write("\r\nusing ");

            #line 36 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(package.Name));

            #line default
            #line hidden
                this.Write(";\r\n\r\n");

            #line 38 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }

            #line default
            #line hidden
            this.Write("\r\n");

            #line 40 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            // Generation of the namespace

            #line default
            #line hidden

            #line 41 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.Namespace(transformation)));

            #line default
            #line hidden
            this.Write(" \r\n{ \r\n\r\n\r\n");

            #line 45 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            // Generation of the Transfo class

            #line default
            #line hidden
            this.Write("public class ");

            #line 46 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.TransformationName(transformation)));

            #line default
            #line hidden
            this.Write(" : GeneratedTransformation {\r\n\r\n\r\n \tprivate readonly ");

            #line 49 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(nameof(IMetaModelInterface)));

            #line default
            #line hidden
            this.Write(" editor;");

            #line 49 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"


            bool hasFunctions = !transformation.OwnedOperation.IsNullOrEmpty();
            // Functions object, if any functions are defined
            if (hasFunctions)
            {
            #line default
            #line hidden
                this.Write("public readonly ");

            #line 55 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.FunctionsInterfaceName(transformation)));

            #line default
            #line hidden
                this.Write(" Functions;");

            #line 55 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }

            // Storing each relation instance once
            foreach (IRelation relation in transformation.Rule.OfType <IRelation>())
            {
            #line default
            #line hidden
                this.Write(" public readonly ");

            #line 61 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.RelationClassName(relation)));

            #line default
            #line hidden
                this.Write(" ");

            #line 61 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.RelationClassName(relation)));

            #line default
            #line hidden
                this.Write("; ");

            #line 61 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }

            // Dictionnaries for keys
            foreach (IKey key in transformation.OwnedKey)
            {
                IList <IProperty> allKeyProperties = new List <IProperty>();
                allKeyProperties.AddRange(key.Part);
                allKeyProperties.AddRange(key.PropertyPaths().Select(pp => pp.Properties.Last()));
                string tupleTypes = string.Join(",", allKeyProperties.Select(p => p.Type.GetRealTypeName()));


            #line default
            #line hidden
                this.Write("internal readonly Dictionary<Tuple<");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(tupleTypes));

            #line default
            #line hidden
                this.Write(">, ");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(key.Identifies.GetRealTypeName()));

            #line default
            #line hidden
                this.Write("> ");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.KeyDictionnaryName(key)));

            #line default
            #line hidden
                this.Write(" = new Dictionary<Tuple<");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(tupleTypes));

            #line default
            #line hidden
                this.Write(">, ");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(key.Identifies.GetRealTypeName()));

            #line default
            #line hidden
                this.Write(">();");

            #line 71 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }

            // Constructor


            #line default
            #line hidden
            this.Write("public ");

            #line 75 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.TransformationName(transformation)));

            #line default
            #line hidden
            this.Write(" (");

            #line 75 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(nameof(IMetaModelInterface)));

            #line default
            #line hidden
            this.Write(" editor ");

            #line 75 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(hasFunctions ? ", " + QvtCodeGeneratorStrings.FunctionsInterfaceName(transformation) + " Functions" : ""));

            #line default
            #line hidden
            this.Write(") {\r\n\r\n\t\t\tthis.editor = editor;");

            #line 77 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"

            foreach (IRelation relation in transformation.Rule.OfType <IRelation>())
            {
            #line default
            #line hidden
                this.Write("  this.");

            #line 80 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.RelationClassName(relation)));

            #line default
            #line hidden
                this.Write(" = new ");

            #line 80 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.RelationClassName(relation)));

            #line default
            #line hidden
                this.Write("(editor, this); \r\n\t\t");

            #line 81 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"

                if (hasFunctions)
                {
            #line default
            #line hidden
                    this.Write("this.Functions = Functions;");

            #line 84 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                }
            }


            #line default
            #line hidden
            this.Write("}");

            #line 87 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"



            foreach (IRelation relation in transformation.Rule.OfType <IRelation>().Where(r => r.IsTopLevel.GetValueOrDefault(false)))
            {
            #line default
            #line hidden
                this.Write("public void ");

            #line 93 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(relation.Name));

            #line default
            #line hidden
                this.Write(" (");

            #line 93 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(RelationTemplateHelper.GenerateRelationParams(true, relation)));

            #line default
            #line hidden
                this.Write(") {\r\n\t\t");

            #line 94 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.RelationClassName(relation)));

            #line default
            #line hidden
                this.Write(".CheckAndEnforce(");

            #line 94 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(RelationTemplateHelper.GenerateRelationParams(false, relation)));

            #line default
            #line hidden
                this.Write(") ;\r\n\t}");

            #line 95 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }



            #line default
            #line hidden
            this.Write("public override void CallTopRelation (string topRelationName, List<object> parame" +
                       "ters)\r\n\t{\r\n\t\tswitch (topRelationName)\r\n\t\t{\r\n\t\t\t");

            #line 103 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            foreach (IRelation relation in transformation.Rule.OfType <IRelation>().Where(r => r.IsTopLevel.GetValueOrDefault(false)))
            {
            #line default
            #line hidden
                this.Write("\t\t\t\tcase \"");

            #line 105 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(relation.Name));

            #line default
            #line hidden
                this.Write("\":\r\n\t\t\t\t\t");

            #line 106 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(relation.Name));

            #line default
            #line hidden
                this.Write("(");

            #line 106 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", relation.Domain.OfType <IRelationDomain>().Select(
                                                                                   d => "(" + d.RootVariable.Type.GetRealTypeName() + ")parameters[" + relation.Domain.IndexOf(d) + "]"))));

            #line default
            #line hidden
                this.Write(");\r\n\t\t\t\t\treturn;\r\n\t\t\t");

            #line 109 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\TransformationTemplate\TransformationMainTemplate.tt"
            }

            #line default
            #line hidden
            this.Write("\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t} // end class\r\n} // end namespace\r\n");
            return(this.GenerationEnvironment.ToString());
        }
        /// <summary>
        /// Create the template output
        /// </summary>
        public virtual string TransformText()
        {
            this.Write("\r\n");
            this.Write("\r\n\r\n");

            #line 18 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"


            // Small hack to bypass limitation of ForTea plugin ( https://github.com/MrJul/ForTea/issues/3 )
            // We redeclare members so that ForTea finds them, and enables code completion etc.
            // The errors can be ignored, as the generated .cs file compiles correctly.
            IRelationalTransformation Transformation = this.Transformation;


            #line default
            #line hidden
            this.Write("\r\n\r\n");

            #line 27 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
            // Generation of the namespace

            #line default
            #line hidden

            #line 28 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.Namespace(Transformation)));

            #line default
            #line hidden
            this.Write(" \r\n{\r\n    public interface ");

            #line 30 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
            this.Write(this.ToStringHelper.ToStringWithCulture(QvtCodeGeneratorStrings.FunctionsInterfaceName(Transformation)));

            #line default
            #line hidden
            this.Write("\r\n    {");

            #line 31 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"

            foreach (IFunction function in Transformation.OwnedOperation.OfType <IFunction>())
            {
                IList <string> args = function.OwnedParameter.Select(p => p.Type.GetRealTypeName() + " " + p.Name).ToList();


            #line default
            #line hidden

            #line 35 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(function.Type == null ? "void" : function.Type.GetRealTypeName()));

            #line default
            #line hidden
                this.Write(" ");

            #line 35 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(function.Name));

            #line default
            #line hidden
                this.Write("(");

            #line 35 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
                this.Write(this.ToStringHelper.ToStringWithCulture(string.Join(",", args)));

            #line default
            #line hidden
                this.Write(" );");

            #line 35 "C:\Users\ebousse\Source\Repos\ChristianDopplerLabors\Software\QvtEnginePerformance\trunk\src\LL.MDE.Components.Qvt.CodeGenerator\CodeGeneration\FunctionsInterfaceTemplate\FunctionsInterfaceTemplate.tt"
            }


            #line default
            #line hidden
            this.Write("}\r\n}\r\n\r\n\r\n\r\n\r\n\r\n");
            return(this.GenerationEnvironment.ToString());
        }
 public static string GenerateAssignmentsFromRelationCall(IRelationCallExp relationCallExp, bool useMetamodelInterface)
 {
     return("transformation." + QvtCodeGeneratorStrings.RelationClassName(relationCallExp.ReferredRelation)
            + ".FindPreviousResult(" + string.Join(",", relationCallExp.Argument.Take(relationCallExp.ReferredRelation.Domain.Count(d => !d.IsEnforceable.GetValueOrDefault())).Select(u => GenerateExpression(u, useMetamodelInterface))) + ")");
 }
        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());
        }
        private static string GenerateSetValue(IPropertyTemplateItem propertyTemplateItem, string resultContainer, IRelation relation, bool useMetamodelInterface)
        {
            StringBuilder      sb = new StringBuilder();
            IObjectTemplateExp objectTemplateExpression = propertyTemplateItem.Value as IObjectTemplateExp;

            // Case ref value
            if (objectTemplateExpression != null)
            {
                IKey transformationKey = ((IRelationalTransformation)relation.Transformation).OwnedKey.FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsTransformationKey = transformationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, transformationKey) : null;

                IKey relationKey = relation.Keys().FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsRelationKey = relationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, relationKey) : null;

                // We always start by creating the empty variable that will contain the object
                sb.AppendLine(objectTemplateExpression.BindsTo.Type.GetRealTypeName() + " " + objectTemplateExpression.BindsTo.Name + " = null;");

                int nbBracketsOpened = 0;

                // If any part of a key applies, then we must generate a test to find a potential existing object
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    // We try to resolve globally and locally, if a global key applies here
                    if (propertyPathsTransformationKey != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("// Trying to resolve the object\'" + objectTemplateExpression.BindsTo.Name + "\' globally using the transformation key");
                        IList <string> tupleTypes      = propertyPathsTransformationKey.Select(pp => pp.Last().ReferredProperty.Type.GetRealTypeName()).Select(name => name + (cSharpPrimitiveTypes.Contains(name) ? "?" : "")).ToList();
                        IList <string> tupleValues     = propertyPathsTransformationKey.Select(pp => GenerateAccess(objectTemplateExpression.BindsTo.Name, pp)).ToList();
                        IList <string> tupleValuesRead = propertyPathsTransformationKey.Select(pp => GenerateExpression(pp.Last().Value, useMetamodelInterface)).ToList();

                        string tupleTypesCombined        = string.Join(",", tupleTypes);
                        string tupleValuesCombined       = string.Join(",", tupleValues);
                        string tupleValuesCombinedRead   = string.Join(",", tupleValuesRead);
                        string accessDictionnaryReadSafe = "transformation."
                                                           + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                           + ".TryGetValue(new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombinedRead + "), out " + objectTemplateExpression.BindsTo.Name + ")";
                        string accessDictionnaryWrite = "transformation."
                                                        + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                        + "[new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombined + ")]";
                        sb.AppendLine(accessDictionnaryReadSafe + ";");

                        // If not found globally with global key, we try to find locally with global key
                        sb.AppendLine("// If the object wasn't found globally, we try to find it locally");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "== null) {");
                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsTransformationKey, useMetamodelInterface));
                        nbBracketsOpened++;

                        // If we found locally with global key, we add to the dictionnary
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(accessDictionnaryWrite + " = " + objectTemplateExpression.BindsTo.Name + ";");

                        // Else we continue with other attempts (local key or object creation)
                        sb.AppendLine("}");
                    }

                    if (propertyPathsRelationKey != null)
                    {
                        sb.AppendLine("// Trying to resolve the object locally using the relation key");

                        if (propertyPathsTransformationKey != null)
                        {
                            sb.AppendLine("else {");
                            nbBracketsOpened++;
                        }

                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsRelationKey, useMetamodelInterface));

                        // If we found something locally, once again we check in the dictionnary and try to update
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                        sb.AppendLine("}");
                    }

                    // In the end we generate a test if we found a candidate
                    sb.AppendLine("// If the object still doesn't exist, we create it");
                    sb.AppendLine("else {");
                    nbBracketsOpened++;
                }

                // In any case, we generate the code to create the object, even if it might end in the conditional due to the keys test
                string beginningCreation = objectTemplateExpression.BindsTo.Name + " = ";
                if (useMetamodelInterface)
                {
                    sb.AppendLine(beginningCreation + " (" + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + ") editor." + nameof(IMetaModelInterface.CreateNewObjectInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\");");
                }
                else
                {
                    string res = beginningCreation;
                    res += "new " + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + "();\n";
                    if (!propertyTemplateItem.ReferredProperty.isMany())
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + " = " + objectTemplateExpression.BindsTo.Name + ";";
                    }
                    else
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + ".Add(" + objectTemplateExpression.BindsTo.Name + ");";
                    }
                    sb.AppendLine(res);
                }

                if (propertyPathsTransformationKey != null)
                {
                    // TODO generate this all the time?
                    sb.AppendLine("// We add the created object to the global cache");
                    sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                }
                // If we generated a conditional for the keys test, we close it now
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    sb.AppendLine("}");
                }

                for (int i = 0; i < nbBracketsOpened - 1; i++)
                {
                    sb.AppendLine("}");
                }
                return(sb.ToString());
            }
            // Case primitive value (variable use or c sharp expression)
            else
            {
                if (useMetamodelInterface)
                {
                    return("editor." + nameof(IMetaModelInterface.AddOrSetInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\", " + GenerateExpression(propertyTemplateItem.Value, true) + " );");
                }
                else
                {
                    return(resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + "=" + GenerateExpression(propertyTemplateItem.Value, false) + ";");
                }
            }
        }