Beispiel #1
0
        public override void Visit(IteratorExp node)
        {
            base.Visit(node);
            node.Source.Accept(this);
            loopStack.Push(node);
            node.Body.Accept(this);

            TranslationOption option = new TranslationOption();

            if (node.Iterator.Count == 1)
            {
                option.FormatString = string.Format("oclX:{0}({{0}}, function(${1}) {{{{ {{1}} }}}})", node.IteratorName, node.Iterator[0].Name);
            }
            else
            {
                option.FormatString = string.Format("oclX:{0}N({{0}}, function({1}) {{{{ {{1}} }}}})", node.IteratorName, node.Iterator.ConcatWithSeparator(vd => "$" + vd.Name, ", "));
            }

            loopStack.Pop();

            SubexpressionTranslations.AddTranslationOption(node, option, node.Source, node.Body);
            if (PredefinedIteratorExpressionRewritings.ContainsKey(node.IteratorName))
            {
                PredefinedIteratorExpressionRewritings[node.IteratorName](node);
            }
        }
Beispiel #2
0
        public override void Visit(OperationCallExp node)
        {
            if (node.ReferredOperation != null && node.ReferredOperation.Tag is NextOperationTag)
            {
                node.Source.Accept(this);
                TranslationOption option = new TranslationOption();
                option.FormatString = "oclX:apply-templates({0})";
                SubexpressionTranslations.AddTranslationOption(node, option, node.Source);
                return;
            }

            base.Visit(node);

            if (OperationRewritings.IsEmpty())
            {
                OperationRewritings[OperationHelper.firstOperationInfo] = AddFirstRewritings;
                OperationRewritings[OperationHelper.lastOperationInfo]  = AddLastRewritings;
                OperationRewritings[OperationHelper.atOperationInfo]    = AddAtRewritings;
            }

            {
                TranslationOption standardTranslation = SubexpressionTranslations.GetSubexpressionTranslation(node);
                OperationInfo?    operationInfo       = OperationHelper.LookupOperation(node, standardTranslation.OptionsContainer.SubExpressions.ToArray());
                if (operationInfo != null && OperationRewritings.ContainsKey(operationInfo.Value))
                {
                    OperationRewritings[operationInfo.Value](node, operationInfo.Value);
                }
            }
        }
Beispiel #3
0
        private void AddAnyOptions(IteratorExp node)
        {
            if (node.Iterator.Count == 1)
            {
                TranslationOption optionFor = new TranslationOption();
                optionFor.FormatString = string.Format("(for ${0} in {{0}} return if ({{1}}) then ${0} else ())[1]",
                                                       node.Iterator[0].Name);
                optionFor.ParenthesisWhenNotTopLevel = true;
                SubexpressionTranslations.AddTranslationOption(node, optionFor);

                bool canRewrite = true;
                SubexpressionCollector collector = new SubexpressionCollector();
                collector.Visit(node);
                List <LoopExp> loopSubExps = collector.Expressions.OfType <LoopExp>().ToList();
                foreach (LoopExp nestedLoopExp in loopSubExps)
                {
                    collector.Clear();
                    nestedLoopExp.Accept(collector);
                    if (collector.ReferredVariables.Contains(node.Iterator[0]))
                    {
                        canRewrite = false;
                        break;
                    }
                }

                if (canRewrite)
                {
                    TranslationOption optionFilter = new TranslationOption();
                    optionFilter.ContextVariableForSubExpressions = node.Iterator[0];
                    optionFilter.FormatString = string.Format("({{0}}[{{1}}])[1]");
                    optionFilter.ParenthesisWhenNotTopLevel = true;
                    SubexpressionTranslations.AddTranslationOption(node, optionFilter);
                }
            }
        }
Beispiel #4
0
        public override void Visit(IteratorExp node)
        {
            base.Visit(node);
            node.Source.Accept(this);
            loopStack.Push(node);
            var prevInsideDynamicEvaluation = insideDynamicEvaluation;

            insideDynamicEvaluation = true;
            node.Body.Accept(this);
            insideDynamicEvaluation = prevInsideDynamicEvaluation;

            string apostrophe = insideDynamicEvaluation ? "''" : "'";

            TranslationOption option = new TranslationOption();

            if (node.Iterator.Count == 1)
            {
                option.FormatString = string.Format("oclX:{0}({{0}}, {2}{1}{2}, {2}{{1}}{2}, $variables)", node.IteratorName, node.Iterator[0].Name, apostrophe);
            }
            else
            {
                option.FormatString = string.Format("oclX:{0}N({{0}}, {2}{1}{2}, {2}{{1}}{2}, $variables)", node.IteratorName, node.Iterator.ConcatWithSeparator(vd => vd.Name, ", "), apostrophe);
            }
            SubexpressionTranslations.AddTranslationOption(node, option, node.Source, node.Body);

            loopStack.Pop();
        }
Beispiel #5
0
        private void AddClosureOptions(IteratorExp node)
        {
            if (node.Iterator.Count == 1)
            {
                if (node.Body is PropertyCallExp)
                {
                    PSMPath path = PSMPathBuilder.BuildPSMPath((PropertyCallExp)node.Body, OclContext, VariableNamer, buildPathParams);

                    // oclX:closure(departments/department, function($c) { $c/subdepartments/department })/name
                    //              departments/department/descendant-or-self::department

                    /*
                     * departments/department + /subdepartments/department
                     */
                    if (PathsJoinable(path, node) && path.IsDownwards && path.Steps.Count > 0)
                    {
                        TranslationOption descendantOption = new TranslationOption();
                        string            lastStep         = path.Steps.Last().ToXPath();
                        if (lastStep.StartsWith("/"))
                        {
                            lastStep = lastStep.Substring(1);
                        }
                        descendantOption.FormatString = string.Format("{{0}}/descendant-or-self::{0}", lastStep);
                        SubexpressionTranslations.AddTranslationOption(node, descendantOption);
                    }
                }
            }
        }
Beispiel #6
0
        public virtual void Visit(PropertyCallExp node, bool isOperationArgument)
        {
            AssignIsPartOfIteratorBody(node);
            PSMPath psmPath = PSMPathBuilder.BuildPSMPath(node, OclContext, VariableNamer, buildPathParams);
            string  xpath   = psmPath.ToXPath(delayFirstVariableStep: true);

            if (!isOperationArgument)
            {
                string wrapString = OperationHelper.WrapAtomicOperand(node, null, 0);
                xpath = string.Format(wrapString, xpath);
            }

            var steps = psmPath.Steps.OfType <IPSMPathStepWithCardinality>().Where(s => s.Lower == 0);

            if (steps.Any())
            {
                Log.AddWarningTaggedFormat("Navigation using '{0}' may result in 'null', which will be an empty sequence in XPath. ", node, steps.ConcatWithSeparator(s => s.ToXPath(), ","));
            }

            TranslationOption option = new TranslationOption();

            if (psmPath.StartingVariableExp != null)
            {
                option.ContextVariableSubstitution = true;
                option.StartingVariable            = psmPath.StartingVariableExp.referredVariable;
            }
            option.FormatString = xpath;
            SubexpressionTranslations.AddTranslationOption(node, option, psmPath.SubExpressions.ToArray());
        }
Beispiel #7
0
 private void AddExistsOptions(IteratorExp node)
 {
     if (node.Iterator.Count == 1)
     {
         TranslationOption option = new TranslationOption();
         option.ParenthesisWhenNotTopLevel = true;
         option.FormatString = string.Format("some ${0} in {{0}} satisfies {{1}}", node.Iterator[0].Name);
         SubexpressionTranslations.AddTranslationOption(node, option);
     }
 }
Beispiel #8
0
        public virtual void Visit(IfExp node)
        {
            node.Condition.Accept(this);
            node.ThenExpression.Accept(this);
            node.ElseExpression.Accept(this);
            TranslationOption option = new TranslationOption();

            option.FormatString = "if ({0}) then {1} else {2}";
            SubexpressionTranslations.AddTranslationOption(node, option, node.Condition, node.ThenExpression, node.ElseExpression);
        }
Beispiel #9
0
        public override void Visit(LetExp node)
        {
            base.Visit(node);
            node.Variable.Value.Accept(this);
            node.InExpression.Accept(this);
            TranslationOption translationOption = new TranslationOption();

            translationOption.FormatString = string.Format("for ${0} in {{0}} return {{1}}", node.Variable.Name);
            SubexpressionTranslations.AddTranslationOption(node, translationOption, node.Variable.Value, node.InExpression);
        }
Beispiel #10
0
        public override void Visit(ClassLiteralExp node)
        {
            base.Visit(node);
            PSMPath psmPath = PSMPathBuilder.BuildPSMPath(node, OclContext, VariableNamer, buildPathParams);
            string  xpath   = psmPath.ToXPath();

            TranslationOption option = new TranslationOption();

            option.FormatString = xpath;
            SubexpressionTranslations.AddTranslationOption(node, option, psmPath.SubExpressions.ToArray());
        }
Beispiel #11
0
        public override void Visit(IterateExp node)
        {
            base.Visit(node);
            node.Source.Accept(this);
            loopStack.Push(node);
            node.Body.Accept(this);
            node.Result.Value.Accept(this);

            TranslationOption option = new TranslationOption();

            option.FormatString = string.Format("oclX:iterate({{0}}, {{1}}, function(${0}, ${1}) {{{{ {{2}} }}}})", node.Iterator[0].Name, node.Result.Name);
            SubexpressionTranslations.AddTranslationOption(node, option, node.Source, node.Result.Value, node.Body);

            loopStack.Pop();
        }
Beispiel #12
0
        public virtual void Visit(VariableExp node)
        {
            AssignIsPartOfIteratorBody(node);
            PSMPath psmPath = PSMPathBuilder.BuildPSMPath(node, OclContext, VariableNamer, buildPathParams);
            string  xpath   = psmPath.ToXPath(delayFirstVariableStep: true);

            TranslationOption option = new TranslationOption();

            if (psmPath.StartingVariableExp != null)
            {
                option.ContextVariableSubstitution = true;
                option.StartingVariable            = psmPath.StartingVariableExp.referredVariable;
            }
            option.FormatString = xpath;
            SubexpressionTranslations.AddTranslationOption(node, option, psmPath.SubExpressions.ToArray());
        }
Beispiel #13
0
        private void AddCollectionAccessRewritings(OperationCallExp operationCallExp, string accesExpr, OperationInfo operationInfo)
        {
            TranslationOption optionIndex = new TranslationOption();

            SubexpressionTranslations.AddTranslationOption(operationCallExp, optionIndex);
            // XPath filter changes context - no variable corresponds to the context in this case
            optionIndex.ContextVariableForSubExpressions = null;
            optionIndex.ContextVariableChangeOnlyIn      = 1;
            // in some special cases, parentheses can be omitted
            bool omitParentheses = false;

            if (operationCallExp.Source is LiteralExp)
            {
                omitParentheses = true;
            }
            if (operationCallExp.Source is VariableExp)
            {
                omitParentheses = true;
            }
            if (!operationInfo.IsXPathInfix && !operationInfo.IsXPathPrefix &&
                !operationInfo.IsAmong(OperationHelper.firstOperationInfo, OperationHelper.lastOperationInfo, OperationHelper.atOperationInfo))
            {
                omitParentheses = true;
            }

            if (omitParentheses)
            {
                optionIndex.FormatString = string.Format("({{0}})[{0}]", accesExpr);
            }
            else
            {
                optionIndex.FormatString = string.Format("({{0}})[{0}]", accesExpr);
            }

            optionIndex.LogMessagesWhenSelected = new List <LogMessage <OclExpression> >();
            optionIndex.LogMessagesWhenSelected.Add(new LogMessage <OclExpression>()
            {
                Tag = operationCallExp, MessageText =
                    "Using indexing returns empty sequence when indexes are out of bounds (no error reported, unlike in OCL). "
            });
        }
Beispiel #14
0
        public override void Visit(IterateExp node)
        {
            base.Visit(node);
            node.Source.Accept(this);
            loopStack.Push(node);
            node.Result.Value.Accept(this);
            var prevInsideDynamicEvaluation = insideDynamicEvaluation;

            insideDynamicEvaluation = true;
            node.Body.Accept(this);
            insideDynamicEvaluation = prevInsideDynamicEvaluation;

            string            apostrophe = insideDynamicEvaluation ? "''" : "'";
            TranslationOption option     = new TranslationOption();

            option.FormatString = string.Format("oclX:iterate({{0}}, {2}{0}{2}, {2}{1}{2}, {2}{{1}}{2}, {2}{{2}}{2}, $variables)", node.Iterator[0].Name, node.Result.Name, apostrophe);

            loopStack.Pop();

            SubexpressionTranslations.AddTranslationOption(node, option, node.Source, node.Result.Value, node.Body);
        }
Beispiel #15
0
        protected override string TupleLiteralToXPath(TupleLiteralExp tupleLiteral, List <OclExpression> subExpressions)
        {
            StringBuilder formatBuilder = new StringBuilder();

            formatBuilder.Append("(map{{");
            foreach (KeyValuePair <string, TupleLiteralPart> kvp in tupleLiteral.Parts)
            {
                kvp.Value.Value.Accept(this);
                formatBuilder.AppendFormat("'{0}' := {{{1}}}, ", kvp.Value.Attribute.Name, subExpressions.Count);
                subExpressions.Add(kvp.Value.Value);
            }
            if (formatBuilder.Length > 0)
            {
                formatBuilder.Length = formatBuilder.Length - 2;
            }
            formatBuilder.Append("}})");
            TranslationOption option = new TranslationOption();

            option.FormatString = formatBuilder.ToString();
            SubexpressionTranslations.AddTranslationOption(tupleLiteral, option, subExpressions.ToArray());
            return(option.FormatString);
        }
Beispiel #16
0
        private void AddCollectOptions(IteratorExp node)
        {
            if (node.Iterator.Count == 1)
            {
                TranslationOption option = new TranslationOption();
                option.ParenthesisWhenNotTopLevel = true;
                option.FormatString = string.Format("for ${0} in {{0}} return {{1}}", node.Iterator[0].Name);
                SubexpressionTranslations.AddTranslationOption(node, option);

                /* when the body of collect is a navigation that can be chained, replace it */
                if (node.Body is PropertyCallExp)
                {
                    PSMPath path = PSMPathBuilder.BuildPSMPath((PropertyCallExp)node.Body, OclContext, VariableNamer, buildPathParams);
                    if (PathsJoinable(path, node))
                    {
                        TranslationOption option2 = new TranslationOption();
                        option2.FormatString = string.Format("{{0}}{0}", path.ToXPath(withoutFirstStep: true));
                        SubexpressionTranslations.AddTranslationOption(node, option2);
                    }
                }
            }
        }
Beispiel #17
0
        protected override string ClassLiteralToXPath(ClassLiteralExp tupleLiteral, List <OclExpression> subExpressions)
        {
            StringBuilder formatBuilder = new StringBuilder();
            string        elementName   = EvolutionAssignmentStack.Peek() != null ? (EvolutionAssignmentStack.Peek().PSMAssociation != null ? EvolutionAssignmentStack.Peek().PSMAssociation.Name: string.Empty): string.Empty;

            formatBuilder.AppendFormat("oclX:genericConstructor('{0}', map {{{{", elementName);
            foreach (KeyValuePair <string, TupleLiteralPart> kvp in tupleLiteral.Parts)
            {
                kvp.Value.Value.Accept(this);
                formatBuilder.AppendFormat("'{0}' := {{{1}}}, ", kvp.Key, subExpressions.Count);
                subExpressions.Add(kvp.Value.Value);
            }
            if (formatBuilder.Length > 0)
            {
                formatBuilder.Length = formatBuilder.Length - 2;
            }
            formatBuilder.Append("}} )");
            TranslationOption option = new TranslationOption();

            option.FormatString = formatBuilder.ToString();
            SubexpressionTranslations.AddTranslationOption(tupleLiteral, option, subExpressions.ToArray());
            return(option.FormatString);
        }
Beispiel #18
0
        public virtual void Visit(CollectionLiteralExp node)
        {
            AssignIsPartOfIteratorBody(node);
            StringBuilder        formatBuilder  = new StringBuilder();
            List <OclExpression> subExpressions = new List <OclExpression>();

            // opening parenthesis of xpath sequence literal
            formatBuilder.Append("(");
            foreach (CollectionLiteralPart clp in node.Parts)
            {
                #region helper function
                Action <OclExpression> appendOne = delegate(OclExpression exp)
                {
                    if (exp is LiteralExp)
                    {
                        formatBuilder.Append("{");
                        formatBuilder.Append(subExpressions.Count);
                        formatBuilder.Append("}");
                    }
                    else
                    {
                        formatBuilder.Append("{(");
                        formatBuilder.Append(subExpressions.Count);
                        formatBuilder.Append(")}");
                    }
                };
                #endregion

                if (clp is CollectionRange)
                {
                    CollectionRange range = ((CollectionRange)clp);
                    range.First.Accept(this);
                    range.Last.Accept(this);

                    appendOne(range.First);
                    subExpressions.Add(range.First);
                    formatBuilder.Append(" to ");
                    appendOne(range.Last);
                    subExpressions.Add(range.Last);
                }

                if (clp is CollectionItem)
                {
                    CollectionItem collectionItem = (CollectionItem)clp;
                    collectionItem.Item.Accept(this);
                    appendOne(collectionItem.Item);
                    subExpressions.Add(collectionItem.Item);
                }
                formatBuilder.Append(", ");
            }

            if (formatBuilder.Length > 1) // remove last comma
            {
                formatBuilder.Length = formatBuilder.Length - 2;
            }

            // closing parenthesis of xpath sequence literal
            formatBuilder.Append(")");

            TranslationOption option = new TranslationOption();
            option.FormatString = formatBuilder.ToString();
            SubexpressionTranslations.AddTranslationOption(node, option, subExpressions.ToArray());
        }
Beispiel #19
0
        private void AddSelectRejectOptions(IteratorExp node, bool select)
        {
            // select and reject differ only in not() applied in filter
            if (node.Iterator.Count == 1)
            {
                TranslationOption optionFor = new TranslationOption();
                optionFor.ParenthesisWhenNotTopLevel = true;
                if (select)
                {
                    optionFor.FormatString = string.Format("for ${0} in {{0}} return if ({{1}}) then ${0} else ()",
                                                           node.Iterator[0].Name);
                }
                else
                {
                    optionFor.FormatString = string.Format(
                        "for ${0} in {{0}} return if (not({{1}})) then ${0} else ()", node.Iterator[0].Name);
                }
                SubexpressionTranslations.AddTranslationOption(node, optionFor);

                /*
                 * this option can be used only when there is no iterator in body, which references the current iterator variable,
                 * because there is no XPath variable corresponding to the iterator variable (context is used instead).
                 */
                {
                    bool canRewrite = true;
                    SubexpressionCollector collector = new SubexpressionCollector();
                    collector.Visit(node);
                    List <LoopExp> loopSubExps = collector.Expressions.OfType <LoopExp>().ToList();
                    foreach (LoopExp nestedLoopExp in loopSubExps)
                    {
                        collector.Clear();
                        nestedLoopExp.Accept(collector);
                        if (collector.ReferredVariables.Contains(node.Iterator[0]))
                        {
                            canRewrite = false;
                            break;
                        }
                    }

                    if (canRewrite)
                    {
                        TranslationOption optionFilter = new TranslationOption();
                        optionFilter.ContextVariableForSubExpressions = node.Iterator[0];
                        if (select)
                        {
                            optionFilter.FormatString = string.Format("{{0}}[{{1}}]");
                        }
                        else
                        {
                            optionFilter.FormatString = string.Format("{{0}}[not({{1}})]");
                        }
                        SubexpressionTranslations.AddTranslationOption(node, optionFilter);
                    }
                    else // translation with let
                    {
                        TranslationOption optionFilterLet = new TranslationOption();
                        optionFilterLet.ContextVariableForSubExpressions = node.Iterator[0];
                        if (select)
                        {
                            optionFilterLet.FormatString = string.Format("{{0}}[let ${0} := . return {{1}}]",
                                                                         node.Iterator[0].Name);
                        }
                        else
                        {
                            optionFilterLet.FormatString = string.Format("{{0}}[let ${0} := . return not({{1}})]",
                                                                         node.Iterator[0].Name);
                        }
                        SubexpressionTranslations.AddTranslationOption(node, optionFilterLet);
                    }
                }
            }
        }