Ejemplo n.º 1
0
        /// <summary>
        /// Helps guess factory methods for each uncovered condition
        /// </summary>
        private void GuessFactorymethods(out SafeSet<Method> allNewSuggestedPUTs, string currPUTSignature, out bool bHasSomeCoveredLocation,
            out bool bAllAreNewLocations, out bool bNoneAreNewLocations)
        {
            PexMeFactoryGuesser pfg = new PexMeFactoryGuesser(this.host);

            HashSet<string> allGivenUpLocations, allCoveredLocations, newUnCoveredLocations;
            //Analyze the current uncovered and previously uncovered locations
            this.pmd.AnalyzePreviousAndCurrentUncoveredLoc(currPUTSignature, out allGivenUpLocations,
                out allCoveredLocations, out newUnCoveredLocations, out bHasSomeCoveredLocation, out bAllAreNewLocations, out bNoneAreNewLocations);

            allNewSuggestedPUTs = new SafeSet<Method>();
            //Iterate through each uncovered location
            foreach (var ucovLocList in pmd.UncoveredLocationDictionary.Values)
            {
                //TODO: Classify the uncovered locations into different groups
                //Because, it can happen that a single code location can have multiple terms which
                //cannot be merged together.
                if (ucovLocList.StoreList.Count == 0)
                    continue;

                //Check whether this location is earlier attempted and is failed. no
                //need to try this location again
                FactorySuggestionStore fss = null;
                string key = null;
                if (this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    key = UncoveredCodeLocationStore.GetKey(ucovLocList.Location.ToString(),
                        ucovLocList.ExplorableType, ucovLocList.TermIndex);

                    //A fix to keep track of uncovered locations in system libraries
                    if (TargetBranchAnalyzer.IsUncoveredLocationInSystemLib(ucovLocList.Location))
                    {
                        fss.UncoveredSystemLibLocations.Add(key);
                    }

                    if (allGivenUpLocations.Contains(key))
                        continue;
                    //Already covered locations can be reported again due to different PUTs or different call sites
                    //if (allCoveredLocations.Contains(key))
                    //    continue;
                    if (fss.PermanentFailedUncoveredLocations.Contains(key))
                        continue;
                    //if (fss.SuccessfulCoveredLocations.Contains(key))
                    //    continue;
                }

                //A single element of ucovLoc is sufficient here
                var ucovLoc = ucovLocList.StoreList[0];
                if (!pfg.TryInferFactoryMethod(ucovLoc, out ucovLoc.SuggestedMethodSetforFactory))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "postprocessor",
                        "Failed to suggest factory methods for uncovered location " + ucovLoc.ToString() + " -> Adding to permanent failed locations");

                    if (fss != null && key != null)
                        fss.PermanentFailedUncoveredLocations.Add(key);

                    continue;
                }

                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        if (suggestedm.IsConstructor)
                            continue;

                        //Check if this is ever explored by this process by getting associated PUT
                        Method pexmethod;
                        bool bretval = PUTGenerator.PUTGenerator.TryRetrievePUT(this.pmd, this.currAssembly, suggestedm, out pexmethod);
                        if (!bretval)
                        {
                            //The suggested method is out of scope of current library and
                            //no need to explore it explicitly
                            continue;
                        }

                        //Ignore self suggestions
                        if (pexmethod == this.pmd.CurrentPUTMethod)
                            continue;
                        var signature = MethodOrFieldAnalyzer.GetMethodSignature(pexmethod);
                        if (this.pmd.AllExploredMethods.Contains(signature))
                            continue;

                        if (this.pmd.PendingExplorationMethods.Contains(signature))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic,
                                "Nested PUTs", "Ignoring the nested PUT due to cycle detection " + signature);
                            continue;
                        }

                        allNewSuggestedPUTs.Add(pexmethod);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds a field to an unsuccessful code location.
        /// </summary>
        /// <param name="location"></param>
        /// <param name="fields"></param>
        public void AddFieldsOfUncoveredCodeLocations(CodeLocation location, SafeList <Field> fields, FieldModificationType fmt,
                                                      Term condition, string terms, int fitnessval, TypeEx explorableType, SafeList <TypeEx> allFieldTypes)
        {
            //No need to process this location.
            if (fields.Count == 0)
            {
                return;
            }

            Field  targetField;
            TypeEx declaringType;   //This declaring type is considered as explorable type in the rest of the analysis

            if (!PexMeFactoryGuesser.GetTargetExplorableField(this, fields, out targetField, out declaringType))
            {
                this.Log.LogError(WikiTopics.MissingWikiTopic, "factoryguesser",
                                  "Failed to retrieve the target field for uncovered location " + location.ToString());
                return;
            }

            //Compare the declaring type and actual explorable type.
            //If there is a inheritance relation, use the actual one
            if (explorableType.IsAssignableTo(declaringType))
            {
                declaringType = explorableType;
            }

            var uclskey = UncoveredCodeLocationStore.GetKey(location.ToString(), declaringType.ToString(), condition.UniqueIndex);
            UncoveredCodeLocationStoreList uclslist;

            if (!this.unCoveredLocationDic.TryGetValue(uclskey, out uclslist))
            {
                uclslist                           = new UncoveredCodeLocationStoreList();
                uclslist.Location                  = location;
                uclslist.ExplorableType            = declaringType.ToString();
                uclslist.TermIndex                 = condition.UniqueIndex;
                this.unCoveredLocationDic[uclskey] = uclslist;
            }

            var ucls = new UncoveredCodeLocationStore();

            ucls.Location       = location;
            ucls.ExplorableType = declaringType;
            ucls.TargetField    = targetField;
            ucls.AllFields.AddRange(fields);
            ucls.AllFieldTypes.AddRange(allFieldTypes);
            ucls.TermIndex = condition.UniqueIndex;
            //add the sequence of method calls
            ucls.MethodCallSequence = new MethodSignatureSequence();
            foreach (var m in this.LastExecutedFactoryMethodCallSequence)
            {
                ucls.MethodCallSequence.Sequence.Add(MethodOrFieldAnalyzer.GetMethodSignature(m));
            }
            ucls.IsADefectDetectingSequence = this.DefectDetectingSequence;
            ucls.CUTMethodCallSequence      = this.LastExecutedCUTMethodCallSequence;

            if (!uclslist.StoreList.Contains(ucls))
            {
                ucls.TextualTerms.Add(terms);
                ucls.DesiredFieldModificationType = fmt;
                ucls.Fitnessvalue = fitnessval;
                uclslist.StoreList.Add(ucls);
            }
        }