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); } }
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); } } }
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); } } } }
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(); }
public override OclExpression Visit(IteratorExp node) { OclExpression sourceAccept = node.Source.Accept(this); loopStacks.Push(node); OclExpression bodyAccept = node.Body.Accept(this); loopStacks.Pop(); List <VariableDeclaration> transVDs = new List <VariableDeclaration>(); foreach (VariableDeclaration vd in node.Iterator) { VariableDeclaration transVD; if (!VariableTranslations.ContainsKey(vd)) { transVD = new VariableDeclaration(vd.Name, null, null); VariableTranslations[vd] = transVD; } else { transVD = VariableTranslations[vd]; } transVDs.Add(transVD); } return(new IteratorExp(sourceAccept, bodyAccept, node.IteratorName, transVDs, node.Type)); }
public void visitIteratorExpBegin(IteratorExp exp) { if (exp.getName() == "collect") { var body = exp.getBody(); if (body is AttributeCallExpImpl) { var bodyImpl = (AttributeCallExpImpl)body; currentClassifier = (CoreClassifier)bodyImpl.getReferredAttribute().getElemOwner(); bodyImpl.accept(this); formula += ","; } else if (body is AssociationEndCallExpImpl) { var bodyImpl = (AssociationEndCallExpImpl)body; var associationEnd = bodyImpl.getReferredAssociationEnd(); bool isOneMultiplicity = associationEnd.isOneMultiplicity(); if (!isOneMultiplicity) { string otherTypeName, otherKeyName, otherName, typeName, name; getTargetAssociationReference(bodyImpl, associationEnd, out otherTypeName, out otherKeyName, out otherName, out typeName, out name); otherFormula = string.Format("=INDEX({0},MATCH([{1}],{0}[{2}],0)", typeName, otherName, name); firstNavigationName = otherName; } navigationLevel++; } else if (body is OperationCallExpImpl) { var bodyImpl = (OperationCallExpImpl)body; // get referred operation name var operation = bodyImpl.getReferredOperation(); var name = operation.getName(); var expsource = (VariableExp)bodyImpl.getSource(); var variable = expsource.getReferredVariable(); var type = variable.getType(); var typeName = type.getName(); formula += string.Format("{0}[{1}]", typeName, name); formula += ","; if (currentClassifier == null) { currentClassifier = (CoreClassifier)operation.getElemOwner(); } } } else if (exp.getName() == "select") { processSelectExpression(exp); } }
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); } }
public void testSelect_01() { List <object> constraints = doTestContextOK("context Film inv: self.tapes->select(t2 | number = 10)->notEmpty()", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(((ModelPropertyCallExp)oclExpression).getSource(), "Set(Tape)", "select", "Tape", "t2"); Assert.IsTrue(((ModelPropertyCallExp)oclExpression).getSource() is IteratorExp); }
public void testExists_06() { List <object> constraints = doTestContextOK("context Film inv: self.tapes->exists(t : Tape | t.theFilm.tapes->forAll(t | t.number = 1 and self.name=\"alex\"))", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "Tape", "t"); Assert.IsTrue(exp.getBody() is IteratorExp); }
public void testExists_02() { List <object> constraints = doTestContextOK("context Film inv: self.tapes->exists(number = 1)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "Tape", "iterator"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), "=", "Boolean"); }
public void testCollect_02() { List <object> constraints = doTestContextOK("context Rental inv: self.itens->collect(number)->notEmpty()", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(((ModelPropertyCallExp)oclExpression).getSource(), "Sequence(String)", "collect", "RentalItem", "iterator"); Console.WriteLine("source = " + exp.getSource().getType().getName()); Assert.IsTrue(((ModelPropertyCallExp)oclExpression).getSource() is IteratorExp); }
public void testOperationCall_07() { List <object> constraints = doTestContextOK("context Film inv: self.getTapes().number = self.getTapes().number", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(((OperationCallExp)oclExpression).getSource(), "Bag(Integer)", "collect", "Tape", "iterator"); checkOperationCallExp(exp.getSource(), "getTapes", "Set(Tape)"); checkAttributeCallExp(exp.getBody(), "number", "Integer"); checkImplicitSource((PropertyCallExp)exp.getBody(), "iterator", "Tape"); }
public void Visit(IteratorExp node) { if (node.Source != null) { node.Source.Accept(this); } sb.Append("->"); sb.Append(node.IteratorName); sb.Append("("); node.Body.Accept(this); sb.Append(")"); }
public void testOperationCall_08() { List <object> constraints = doTestContextOK("context Film inv: self.getTapes().theFilm = self.getTapes().theFilm", getCurrentMethodName()); OclExpression oclExpression = ((OperationCallExp)getConstraintExpression(constraints)).getSource(); IteratorExp exp = checkIteratorExp(oclExpression, "Bag(Film)", "collect", "Tape", "iterator"); checkOperationCallExp(exp.getSource(), "getTapes", "Set(Tape)"); checkAssociationEndCallExp(exp.getBody(), "theFilm", "Film"); checkImplicitSource((PropertyCallExp)exp.getBody(), "iterator", "Tape"); }
public void testImplicitCollect_02() { List <object> constraints = doTestContextOK("context Client inv : self.Rental.maxDaysToReturn->exists(x | x > 5)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "Integer", "x"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), ">", "Boolean"); checkIteratorExp(exp.getSource(), "Bag(Integer)", "collect", "Rental", "iterator"); Assert.IsTrue(((IteratorExp)exp.getSource()).getBody() is AttributeCallExp); }
public void testImplicitCollect_04() { List <object> constraints = doTestContextOK("context Tape inv: self.theFilm.getTapes().theFilm.getTapes()->exists( x | x.number > 5)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "Tape", "x"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), ">", "Boolean"); checkIteratorExp(exp.getSource(), "Bag(Tape)", "collect", "Film", "iterator"); Assert.IsTrue(((IteratorExp)exp.getSource()).getBody() is OperationCallExp); }
public void testImplicitCollect_06() { List <object> constraints = doTestContextOK("context Film inv: self.Reservation.Person.EmployeeRanking[bosses]->exists( x | x.score > 5)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "EmployeeRanking", "x"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), ">", "Boolean"); checkIteratorExp(exp.getSource(), "Bag(EmployeeRanking)", "collect", "Person", "iterator"); Assert.IsTrue(((IteratorExp)exp.getSource()).getBody() is AssociationClassCallExp); }
public void testIteratorExp_02() { List <object> constraints = doTestContextOK("context Rental inv: self.itens.Rental = self.itens.Rental", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(((OperationCallExp)oclExpression).getSource(), "Sequence(Rental)", "collect", "RentalItem", "iterator"); checkAssociationEndCallExp(exp.getBody(), "Rental", "Rental"); checkImplicitSource((PropertyCallExp)exp.getBody(), "iterator", "RentalItem"); checkAssociationEndCallExp(exp.getSource(), "itens", "OrderedSet(RentalItem)"); checkImplicitSource((PropertyCallExp)exp.getSource(), "self", "Rental"); }
public override bool Visit(IteratorExp node) { // forAll apod. bool sourceAccept = node.Source.Accept(this); OclExpression source = node.Source; while (source is IteratorExp) { if (collectionIteratorsPreservingType.Contains(((IteratorExp)source).IteratorName)) { source = ((IteratorExp)source).Source; } else { break; } } if (source is PropertyCallExp) { // find path to source PIMPath sourcePath = PIMPathBuilder.BuildPIMPath((PropertyCallExp)source); List <PSMPath> navigations = FindNavigationsForPIMNavigation(sourcePath); foreach (VariableDeclaration vd in node.Iterator) { VariableClassMappings.CreateSubCollectionIfNeeded(vd); foreach (PSMPath psmNavigation in navigations) { VariableClassMappings[vd].Add(psmNavigation.LastClass); } } } else if (source is IteratorExp) { foreach (VariableDeclaration vd in node.Iterator) { if (vd.PropertyType.Tag != null) { VariableClassMappings.CreateSubCollectionIfNeeded(vd); VariableClassMappings[vd].AddRange(GetInterpretations((PIMClass)vd.PropertyType.Tag)); } } } loopStacks.Push(node); bool bodyAccept = node.Body.Accept(this); loopStacks.Pop(); return(sourceAccept && bodyAccept); }
private IExpression GetExpression(SelectContext context, IteratorExp iterator) { GetExpression(context, (dynamic)iterator.Source); var alias = iterator.Iterator[0].Name; if (iterator.Source is OperationCallExp operationCall && operationCall.ReferredOperation == Operator.AllInstances) { var table = context.Body.FromItem as Table; table.Alias = new Alias { Name = alias }; context.Variables.Add(alias, table.Name); }
public void testImplicitCollect_01() { List <object> constraints = doTestContextOK("context Client inv : self.Rental.itens->exists(i | i.number = 1)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "RentalItem", "i"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), "=", "Boolean"); checkIteratorExp(exp.getSource(), "Sequence(RentalItem)", "collect", "Rental", "iterator"); Assert.IsTrue(((IteratorExp)exp.getSource()).getBody() is AssociationEndCallExp); }
public void testCollectTuple_01() { List <object> constraints = doTestContextOK("context Film inv: self.Reservation.Person->collect(Tuple{a = age, b : Sequence(Integer) = bosses.age->asSequence()})->exists(x | x.a > 10)", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); IteratorExp exp = checkIteratorExp(oclExpression, "Boolean", "exists", "Tuple(a : Integer, b : Sequence(Integer))", "x"); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), ">", "Boolean"); checkIteratorExp(exp.getSource(), "Bag(Tuple(a : Integer, b : Sequence(Integer)))", "collect", "Person", "iterator"); Assert.IsTrue(((IteratorExp)exp.getSource()).getBody() is TupleLiteralExp); }
protected IteratorExp checkIteratorExp(OclExpression oclExpression, String typeName, String name, String iteratorType, String iteratorName) { Assert.IsTrue(oclExpression is IteratorExp); IteratorExp exp = (IteratorExp)oclExpression; Assert.AreEqual(typeName, exp.getType().getName()); Assert.AreEqual(name, exp.getName()); Assert.AreEqual(1, exp.getIterators().Count); VariableDeclaration varDecl = (VariableDeclaration)exp.getIterators()[0]; Assert.AreEqual(iteratorName, varDecl.getVarName()); Assert.AreEqual(iteratorType, varDecl.getType().getName()); return(exp); }
public void Visit(IteratorExp node) { if (node.Source != null) { node.Source.Accept(this); sb.Append("->"); } sb.Append(node.IteratorName); sb.Append("("); if (node.Iterator != null) { PrintArgs(node.Iterator, ",", (v) => { VariableDeclaration(v); }); sb.Append(" | "); } node.Body.Accept(this); sb.Append(")"); }
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); } } } }
public void testForAll_01() { List <object> constraints = doTestContextOK("context Film inv: self.tapes->forAll(t1 : Tape, t2 : Tape | t1 <> t2 and t1.number = 1 and self.name = \"alex\")", getCurrentMethodName()); OclExpression oclExpression = getConstraintExpression(constraints); Assert.IsTrue(oclExpression is IteratorExp); IteratorExp exp = (IteratorExp)oclExpression; Assert.AreEqual("Boolean", exp.getType().getName()); Assert.AreEqual("forAll", exp.getName()); Assert.AreEqual(2, exp.getIterators().Count); VariableDeclaration v1 = (VariableDeclaration)exp.getIterators()[0]; VariableDeclaration v2 = (VariableDeclaration)exp.getIterators()[1]; Assert.AreEqual("t1", v1.getName()); Assert.AreEqual("t2", v2.getName()); Assert.AreEqual("Tape", v1.getType().getName()); Assert.IsTrue(exp.getBody() is OperationCallExp); checkOperationCallExp(exp.getBody(), "and", "Boolean"); }
public void testIteratorExp() { AstOclModelElementFactory factory1 = AstOclModelElementFactoryManager.getInstance(umlModel.getOclPackage()); VariableDeclaration variable = factory1.createVariableDeclaration("abc", getClassifier("Distributor"), null); VariableExp source = factory1.createVariableExp(variable); VariableDeclaration iter = factory1.createVariableDeclaration("iter", getClassifier("SpecialFilm"), null); VariableExp iterRef = factory1.createVariableExp(iter); CoreAttribute attr = getClassifier("SpecialFilm").lookupAttribute("name"); AttributeCallExp body = factory1.createAttributeCallExp(iterRef, attr, false); CoreClassifier setSpecialFilm = factory1.createSetType(getClassifier("SpecialFilm")); List <object> iterators = new List <object> (); iterators.Add(iter); IteratorExp exp = factory1.createIteratorExp("select", setSpecialFilm, source, body, iterators); Assert.AreEqual("abc->select(iter : SpecialFilm | iter.name)", exp.ToString()); Assert.AreEqual("Set(SpecialFilm)", exp.getType().getName()); }
private bool PathsJoinable(PSMPath startingPath, IteratorExp node) { return(startingPath.StartingVariableExp.referredVariable == node.Iterator[0] && startingPath.Steps.Count > 1); }
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); } } } }
public virtual void Visit(IteratorExp node) { AssignIsPartOfIteratorBody(node); }