/// <summary>
 /// Merges the other return value with this one
 /// </summary>
 /// <param name="previous">The previous ReturnValueElement which lead to this ReturnValueElement</param>
 /// <param name="other">The other return value to merge with</param>
 public void Merge(ReturnValueElement previous, ReturnValue other)
 {
     foreach (ReturnValueElement elem in other.Values)
     {
         Add(elem.Value, previous);
     }
 }
示例#2
0
        /// <summary>
        ///     Indicates that the referenced value has been removed
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        private bool ValueIsRemoved(ReturnValueElement element)
        {
            bool retVal = false;

            ModelElement model = element.Value as ModelElement;

            if (model != null)
            {
                retVal = model.IsRemoved;
            }

            return(retVal);
        }
        /// <summary>
        ///     Performs the semantic analysis of the expression
        /// </summary>
        /// <param name="instance">the reference instance on which this element should analysed</param>
        /// <param name="expectation">Indicates the kind of element we are looking for</param>
        /// <returns>True if semantic analysis should be continued</returns>
        public override bool SemanticAnalysis(INamable instance, BaseFilter expectation)
        {
            bool retVal = base.SemanticAnalysis(instance, expectation);

            if (retVal)
            {
                Ref = null;

                ReturnValue tmp = GetReferences(instance, expectation, false);

                if (tmp.IsUnique)
                {
                    // Unique element has been found. Reference it and perform the semantic analysis
                    // on all dereferenced expression, now that the context is known for each expression
                    Ref = tmp.Values[0].Value;
                    StaticUsage.AddUsage(Ref, Root, null);

                    References         referenceFilter;
                    ReturnValueElement current = tmp.Values[0];
                    for (int i = Arguments.Count - 1; i > 0; i--)
                    {
                        referenceFilter = new References(current.Value);
                        current         = current.PreviousElement;
                        Arguments[i].SemanticAnalysis(current.Value, referenceFilter);
                        StaticUsage.AddUsages(Arguments[i].StaticUsage, null);
                        StaticUsage.AddUsage(Arguments[i].Ref, Root, null);
                    }
                    referenceFilter = new References(current.Value);
                    Arguments[0].SemanticAnalysis(null, referenceFilter);
                    StaticUsage.AddUsages(Arguments[0].StaticUsage, null);
                    StaticUsage.AddUsage(Arguments[0].Ref, Root, null);
                }
                else if (tmp.IsAmbiguous)
                {
                    // Several possible interpretations for this deref expression, not allowed
                    AddError("Expression " + ToString() + " may have several interpretations " + tmp +
                             ", please disambiguate", RuleChecksEnum.SemanticAnalysisError);
                }
                else
                {
                    // No possible interpretation for this deref expression, not allowed
                    AddError("Expression " + ToString() + " has no interpretation", RuleChecksEnum.SemanticAnalysisError);
                }
            }

            return(retVal);
        }
        /// <summary>
        /// Adds a new value in the set of return values
        /// </summary>
        /// <param name="value">The value to add</param>
        /// <param name="previous">The previous element in the chain</param>
        public void Add(Utils.INamable value, ReturnValueElement previous = null)
        {
            if (value != null)
            {
                bool found = false;
                foreach (ReturnValueElement elem in Values)
                {
                    if (elem.Value == value)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Values.Add(new ReturnValueElement(value, previous));
                }
            }
        }
示例#5
0
        /// <summary>
        ///     Adds a new value in the set of return values
        /// </summary>
        /// <param name="value">The value to add</param>
        /// <param name="previous">The previous element in the chain</param>
        /// <param name="asType"></param>
        public void Add(INamable value, ReturnValueElement previous = null, bool asType = false)
        {
            if (value != null)
            {
                ReturnValueElement element = new ReturnValueElement(value, previous, asType);
                foreach (ReturnValueElement elem in Values)
                {
                    if (elem.CompareTo(element) == 0)
                    {
                        element = null;
                        break;
                    }
                }

                if (element != null)
                {
                    Values.Add(element);
                }
            }
        }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="value"></param>
 /// <param name="previous"></param>
 public ReturnValueElement(Utils.INamable value, ReturnValueElement previous = null)
 {
     PreviousElement = previous;
     Value           = value;
 }
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="value"></param>
 /// <param name="previous"></param>
 public ReturnValueElement(Utils.INamable value, ReturnValueElement previous = null)
 {
     PreviousElement = previous;
     Value = value;
 }
 /// <summary>
 /// Merges the other return value with this one
 /// </summary>
 /// <param name="previous">The previous ReturnValueElement which lead to this ReturnValueElement</param>
 /// <param name="other">The other return value to merge with</param>
 public void Merge(ReturnValueElement previous, ReturnValue other)
 {
     foreach (ReturnValueElement elem in other.Values)
     {
         Add(elem.Value, previous);
     }
 }
        /// <summary>
        /// Adds a new value in the set of return values
        /// </summary>
        /// <param name="value">The value to add</param>
        /// <param name="previous">The previous element in the chain</param>
        public void Add(Utils.INamable value, ReturnValueElement previous = null)
        {
            if (value != null)
            {
                bool found = false;
                foreach (ReturnValueElement elem in Values)
                {
                    if (elem.Value == value)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    Values.Add(new ReturnValueElement(value, previous));
                }
            }
        }
示例#10
0
        /// <summary>
        /// Performs the semantic analysis of the expression
        /// </summary>
        /// <param name="instance">the reference instance on which this element should analysed</param>
        /// <paraparam name="expectation">Indicates the kind of element we are looking for</paraparam>
        /// <returns>True if semantic analysis should be continued</returns>
        public override bool SemanticAnalysis(Utils.INamable instance, Filter.AcceptableChoice expectation)
        {
            bool retVal = base.SemanticAnalysis(instance, expectation);

            if (retVal)
            {
                Ref = null;

                ReturnValue tmp = Arguments[0].getReferences(instance, Filter.AllMatches, false);
                if (tmp.IsEmpty)
                {
                    tmp = Arguments[0].getReferenceTypes(instance, Filter.AllMatches, false);
                }

                if (!tmp.IsEmpty)
                {
                    for (int i = 1; i < Arguments.Count; i++)
                    {
                        ReturnValue tmp2 = tmp;
                        tmp = new ReturnValue(Arguments[i]);

                        foreach (ReturnValueElement elem in tmp2.Values)
                        {
                            tmp.Merge(elem, Arguments[i].getReferences(elem.Value, Filter.AllMatches, i == (Arguments.Count - 1)));
                        }

                        if (tmp.IsEmpty)
                        {
                            AddError("Cannot find " + Arguments[i].ToString() + " in " + Arguments[i - 1].ToString());
                        }
                    }
                }
                else
                {
                    AddError("Cannot evaluate " + Arguments[0].ToString());
                }

                tmp.filter(expectation);
                if (tmp.IsUnique)
                {
                    // Unique element has been found. Reference it and perform the semantic analysis
                    // on all dereferenced expression, now that the context is known for each expression
                    Ref = tmp.Values[0].Value;

                    ReturnValueElement current = tmp.Values[0];
                    for (int i = Arguments.Count - 1; i > 0; i--)
                    {
                        current = current.PreviousElement;
                        Arguments[i].SemanticAnalysis(current.Value);
                    }
                    Arguments[0].SemanticAnalysis();
                }
                else if (tmp.IsAmbiguous)
                {
                    // Several possible interpretations for this deref expression, not allowed
                    AddError("Expression " + ToString() + " may have several interpretations " + tmp.ToString() + ", please disambiguate");
                }
                else
                {
                    // No possible interpretation for this deref expression, not allowed
                    AddError("Expression " + ToString() + " has no interpretation");
                }
            }

            return(retVal);
        }
        /// <summary>
        ///     Indicates that the referenced value has been removed
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        private bool ValueIsRemoved(ReturnValueElement element)
        {
            bool retVal = false;

            ModelElement model = element.Value as ModelElement;
            if (model != null)
            {
                retVal = model.IsRemoved;
            }

            return retVal;
        }
        /// <summary>
        ///     Adds a new value in the set of return values
        /// </summary>
        /// <param name="value">The value to add</param>
        /// <param name="previous">The previous element in the chain</param>
        /// <param name="asType"></param>
        public void Add(INamable value, ReturnValueElement previous = null, bool asType = false)
        {
            if (value != null)
            {
                ReturnValueElement element = new ReturnValueElement(value, previous, asType);
                foreach (ReturnValueElement elem in Values)
                {
                    if (elem.CompareTo(element) == 0)
                    {
                        element = null;
                        break;
                    }
                }

                if (element != null)
                {
                    Values.Add(element);
                }
            }
        }
示例#13
0
        /// <summary>
        ///     Provides the possible references for this expression (only available during semantic analysis)
        /// </summary>
        /// <param name="instance">the instance on which this element should be found.</param>
        /// <param name="expectation">the expectation on the element found</param>
        /// <param name="last">indicates that this is the last element in a dereference chain</param>
        /// <returns></returns>
        public override ReturnValue GetReferences(INamable instance, BaseFilter expectation, bool last)
        {
            ReturnValue retVal = Arguments[0].GetReferences(instance, AllMatches.INSTANCE, false);

            if (retVal.IsEmpty)
            {
                retVal = Arguments[0].GetReferenceTypes(instance, AllMatches.INSTANCE, false);
            }

            // When variables & parameters are found, only consider the first one
            // which is the one that is closer in the tree
            {
                ReturnValue tmp2 = retVal;
                retVal = new ReturnValue();

                ReturnValueElement variable = null;
                foreach (ReturnValueElement elem in tmp2.Values)
                {
                    if (elem.Value is Parameter || elem.Value is IVariable)
                    {
                        if (variable == null)
                        {
                            variable = elem;
                            retVal.Values.Add(elem);
                        }
                    }
                    else
                    {
                        retVal.Values.Add(elem);
                    }
                }
            }

            if (retVal.IsUnique)
            {
                Arguments[0].Ref = retVal.Values[0].Value;
            }

            if (!retVal.IsEmpty)
            {
                for (int i = 1; i < Arguments.Count; i++)
                {
                    ReturnValue tmp2 = retVal;
                    retVal = new ReturnValue(Arguments[i]);

                    foreach (ReturnValueElement elem in tmp2.Values)
                    {
                        bool         removed = false;
                        ModelElement model   = elem.Value as ModelElement;
                        if (model != null)
                        {
                            removed = model.IsRemoved;
                        }

                        if (!removed)
                        {
                            retVal.Merge(elem,
                                         Arguments[i].GetReferences(elem.Value, AllMatches.INSTANCE, i == (Arguments.Count - 1)));
                        }
                    }

                    if (retVal.IsEmpty)
                    {
                        AddError("Cannot find " + Arguments[i] + " in " + Arguments[i - 1], RuleChecksEnum.SemanticAnalysisError);
                    }

                    if (retVal.IsUnique)
                    {
                        Arguments[i].Ref = retVal.Values[0].Value;
                    }
                }
            }
            else
            {
                AddError("Cannot evaluate " + Arguments[0], RuleChecksEnum.SemanticAnalysisError);
            }

            retVal.Filter(expectation);

            return(retVal);
        }
示例#14
0
        /// <summary>
        ///     Filters out value according to predicate
        /// </summary>
        /// <param name="accept"></param>
        public void Filter(BaseFilter accept)
        {
            ApplyUpdates();
            DiscardRemoved();

            // Only keep the most specific elements.
            string mostSpecific = null;

            foreach (ReturnValueElement element in Values)
            {
                if (accept.AcceptableChoice(element.Value))
                {
                    if (mostSpecific == null)
                    {
                        mostSpecific = element.Value.FullName;
                    }
                    else
                    {
                        if (mostSpecific.Length < element.Value.FullName.Length)
                        {
                            mostSpecific = element.Value.FullName;
                        }
                    }
                }
            }

            // if the filtering is about variables, ensure that there is at least one variable in the element chain
            if (accept is IsVariable)
            {
                List <ReturnValueElement> tmp = new List <ReturnValueElement>();
                foreach (ReturnValueElement element in Values)
                {
                    bool variableFound         = false;
                    bool onlyStructureElement  = true;
                    ReturnValueElement current = element;
                    while (!variableFound && current != null)
                    {
                        variableFound = IsStrictVariableOrValue.INSTANCE.AcceptableChoice(current.Value) ||
                                        current.AsType;
                        onlyStructureElement = onlyStructureElement && current.Value is StructureElement;
                        current = current.PreviousElement;
                    }

                    if (variableFound)
                    {
                        tmp.Add(element);
                    }
                    else if (onlyStructureElement)
                    {
                        tmp.Add(element);
                    }
                }

                // HaCK : If tmp is empty, this indicates that the filter above is too restrictive.
                // Keep the original set
                if (tmp.Count > 0)
                {
                    Values = tmp;
                }
            }

            // Build a new list with the filtered out elements
            bool variable = false;

            {
                List <ReturnValueElement> tmp = new List <ReturnValueElement>();
                foreach (ReturnValueElement element in Values)
                {
                    if (accept.AcceptableChoice(element.Value) &&
                        (mostSpecific == null || mostSpecific.Equals(element.Value.FullName)))
                    {
                        tmp.Add(element);
                        variable = variable || element.Value is IVariable;
                    }
                }
                Values = tmp;
            }

            // HaCK : If both Variable and StructureElement are found, only keep the variable
            if (variable)
            {
                List <ReturnValueElement> tmp = new List <ReturnValueElement>();
                foreach (ReturnValueElement element in Values)
                {
                    if (!(element.Value is StructureElement) && !(element.Value is Type))
                    {
                        tmp.Add(element);
                    }
                }

                Values = tmp;
            }
        }