/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (ListExpression != null) { ListExpression.CheckExpression(); Collection listExpressionType = ListExpression.GetExpressionType() as Collection; if (listExpressionType == null) { Root.AddError("Target does not references a list"); } } else { Root.AddError("List should be specified"); } if (ConditionExpression != null) { ConditionExpression.CheckExpression(); } if (AppliedStatement != null) { AppliedStatement.CheckStatement(); } else { Root.AddError("Procedure should be specified in the APPLY statement"); } }
/// <summary> /// Performs the semantic analysis of the statement /// </summary> /// <param name="instance">the reference instance on which this element should analysed</param> /// <returns>True if semantic analysis should be continued</returns> public override bool SemanticAnalysis(INamable instance = null) { bool retVal = base.SemanticAnalysis(instance); if (retVal) { // ListExpression if (ListExpression != null) { ListExpression.SemanticAnalysis(instance, IsRightSide.INSTANCE); StaticUsage.AddUsages(ListExpression.StaticUsage, Usage.ModeEnum.ReadAndWrite); Collection collectionType = ListExpression.GetExpressionType() as Collection; if (collectionType != null) { IteratorVariable.Type = collectionType.Type; } } else { AddError("List expression not provided", RuleChecksEnum.SemanticAnalysisError); } // ConditionExpression if (ConditionExpression != null) { ConditionExpression.SemanticAnalysis(instance); StaticUsage.AddUsages(ConditionExpression.StaticUsage, Usage.ModeEnum.Read); } if (AppliedStatement != null) { AppliedStatement.SemanticAnalysis(instance); StaticUsage.AddUsages(AppliedStatement.StaticUsage, Usage.ModeEnum.Call); } else { AddError("Applied statement not provided", RuleChecksEnum.SemanticAnalysisError); } } return(retVal); }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> /// <param name="runner"></param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply, Runner runner) { // Explain what happens in this statement explanation = ExplanationPart.CreateSubExplanation(explanation, this); IVariable variable = ListExpression.GetVariable(context); if (variable != null) { if (variable.Value != EfsSystem.Instance.EmptyValue) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue; variable.Value = listValue; ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue); if (listValue != null) { int token = context.LocalScope.PushContext(); context.LocalScope.SetVariable(IteratorVariable); bool elementFound = false; bool matchingElementFound = false; foreach (IValue value in listValue.Val) { if (value != EfsSystem.Instance.EmptyValue) { // All elements should always be != from EmptyValue elementFound = true; IteratorVariable.Value = value; if (ConditionSatisfied(context, explanation)) { matchingElementFound = true; AppliedStatement.GetChanges(context, changes, explanation, apply, runner); } } } if (!elementFound) { ExplanationPart.CreateSubExplanation(explanation, "Empty collection"); } else if (!matchingElementFound) { ExplanationPart.CreateSubExplanation(explanation, "No matching element found"); } context.LocalScope.PopContext(token); } else { Root.AddError("List expression does not evaluate to a list value"); } } } else { Root.AddError("Cannot find variable for " + ListExpression); } }
/// <summary> /// Provides the list of elements read by this statement /// </summary> /// <param name="retVal">the list to fill</param> public override void ReadElements(List <ITypedElement> retVal) { AppliedStatement.ReadElements(retVal); }
/// <summary> /// Provides the list of update statements induced by this statement /// </summary> /// <param name="retVal">the list to fill</param> public override void UpdateStatements(List <VariableUpdateStatement> retVal) { AppliedStatement.UpdateStatements(retVal); }
/// <summary> /// Provides the statement which modifies the variable /// </summary> /// <param name="variable"></param> /// <returns>null if no statement modifies the element</returns> public override VariableUpdateStatement Modifies(ITypedElement variable) { VariableUpdateStatement retVal = AppliedStatement.Modifies(variable); return(retVal); }