예제 #1
0
        /// <summary>
        /// Adds a default method-call sequence that represents the first execution
        /// of the PUT
        /// </summary>
        internal void AddDefaultSequence(PexMeDynamicDatabase pmd, MethodSignatureSequence defaultSeq)
        {
            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;

            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
            {
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);
            }

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
                putIndependentMssl.Add(defaultSeq);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;

            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
                putSpecificMssl.Add(defaultSeq);
            }
        }
예제 #2
0
        public static bool TryCheckReturnTypeOfMethod(PexMeDynamicDatabase pmd, TypeDefinition tdef,
                                                      MethodDefinition mdef, TypeEx targetTypeEx, out Method producingMethod)
        {
            var retType = mdef.ResultType;

            if (retType.ToString() == targetTypeEx.FullName)
            {
                producingMethod = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(pmd, tdef),
                                                   MethodOrFieldAnalyzer.GetGenericMethodParameters(pmd, mdef));
                return(true);
            }

            //Get the actual type of return type and see whether it is assinable
            TypeEx retTypeEx;

            if (MethodOrFieldAnalyzer.TryGetTypeExFromName(pmd, pmd.CurrAssembly, retType.ToString(), out retTypeEx))
            {
                if (targetTypeEx.IsAssignableTo(retTypeEx))
                {
                    producingMethod = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(pmd, tdef),
                                                       MethodOrFieldAnalyzer.GetGenericMethodParameters(pmd, mdef));
                    return(true);
                }
            }

            producingMethod = null;
            return(false);
        }
        private void ExtractMethodsAndProperties(TypeEx explorableType, SafeDictionary <string, Method> methodNameToMethodMapper,
                                                 SafeDictionary <string, Property> propertyNameToPropertyMapper)
        {
            for (TypeEx type = explorableType; type != null; type = type.BaseType)
            {
                if (type.ToString() == "System.Object")
                {
                    continue;
                }

                var typedef = type.Definition;
                foreach (var constructor in typedef.DeclaredInstanceConstructors)
                {
                    Method method = constructor.Instantiate(type.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(host, constructor));
                    methodNameToMethodMapper[MethodOrFieldAnalyzer.GetMethodSignature(constructor)] = method;
                }

                foreach (var methodDefinition in typedef.DeclaredInstanceMethods)
                {
                    Method method = methodDefinition.Instantiate(type.GenericTypeArguments, MethodOrFieldAnalyzer.GetGenericMethodParameters(host, methodDefinition));
                    methodNameToMethodMapper[MethodOrFieldAnalyzer.GetMethodSignature(method)] = method;
                }

                foreach (var propDefinition in typedef.DeclaredProperties)
                {
                    Property prop = propDefinition.Instantiate(type.GenericTypeArguments);
                    if (prop.Setter != null)
                    {
                        propertyNameToPropertyMapper[MethodOrFieldAnalyzer.GetMethodSignature(prop.Setter)] = prop;
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Gets invoked befor the state of the exploration
        /// </summary>
        /// <param name="host"></param>
        /// <returns></returns>
        object IPexExplorationPackage.BeforeExploration(IPexExplorationComponent host)
        {
            this.pmd.CurrentPUTMethod = host.ExplorationServices.CurrentExploration.Exploration.Method;
            var currPUTSignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);

            //Activate the methods of the current PUT from dormant
            foreach (var fss in pmd.FactorySuggestionsDictionary.Values)
            {
                foreach (var pucls in fss.locationStoreSpecificSequences.Values)
                {
                    if (pucls.IsDormat())
                    {
                        pucls.ActivateFromDormant(currPUTSignature);
                    }
                }
            }
            pmd.PendingExplorationMethods.Add(currPUTSignature);

            //This code includes MSeqGen related stuff, primarily for evaluating the combined approach
            //if (PexMeConstants.ENABLE_MSEQGEN_RECOMMENDER)
            //{
            //    var explorableManager = host.ExplorationServices.ExplorableManager;
            //    int numMethodsRecommended = 0;
            //    foreach (var explorableCandidate in mseqgen.GetExplorableCandidates())
            //    {
            //        explorableManager.AddExplorableCandidate(explorableCandidate);
            //        numMethodsRecommended++;
            //    }
            //
            //    host.Log.LogMessage("MSeqGenRecommender", "Recommended " + numMethodsRecommended + " factory methods");
            //}

            return(null);
        }
예제 #5
0
        private static SafeDictionary <Method, MethodStore> GetMethodDictionary(IPexComponent host,
                                                                                System.Collections.Generic.Dictionary <string, PersistentMethodStore> pmethoddic)
        {
            var methoddic = new SafeDictionary <Method, MethodStore>();

            foreach (var methodstr in pmethoddic.Keys)
            {
                Method method;
                bool   bresult = MethodOrFieldAnalyzer.TryGetMethodFromPersistentStringForm(host, methodstr, out method);
                if (!bresult)
                {
                    continue;
                }

                MethodStore ms;
                bresult = PersistentMethodStore.TryGetMethodStore(host, pmethoddic[methodstr], out ms);
                if (!bresult)
                {
                    continue;
                }

                //SafeDebug.Assume(bresult, "Failed to get method from persistent store!!!");
                methoddic[method] = ms;
            }

            return(methoddic);
        }
예제 #6
0
        /// <summary>
        /// Function the retrieves associated Persistent store for each MethodStore
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="pms"></param>
        /// <returns></returns>
        public static bool TryGetPersistentMethodStore(MethodStore ms, out PersistentMethodStore pms)
        {
            pms            = new PersistentMethodStore();
            pms.methodName = MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(ms.methodName);

            //foreach (var field in ms.ReadFields)
            //    pms.ReadFields.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfField(field));

            foreach (var field in ms.WriteFields)
            {
                pms.WriteFields.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfField(field));
            }

            //foreach (var typeex in ms.CallingMethods.Keys)
            //{
            //    HashSet<string> wmethods = new HashSet<string>();
            //    pms.CallingMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfTypeEx(typeex), wmethods);

            //    var methods = ms.CallingMethods[typeex];
            //    var assemblyname = typeex.Definition.Module.Assembly.Location;
            //    var typename = typeex.FullName;

            //    foreach (var m in methods)
            //    {
            //        wmethods.Add(assemblyname + PexMeConstants.PexMePersistenceFormSeparator
            //            + typename + PexMeConstants.PexMePersistenceFormSeparator
            //            + MethodOrFieldAnalyzer.GetMethodSignature(m));
            //    }
            //}

            //foreach (var calledMethod in ms.CalledMethods)
            //    pms.CalledMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(calledMethod));

            return(true);
        }
예제 #7
0
        public void AfterExecution(IPexComponent host, object data)
        {
            if (this.pmd.CurrentPUTMethod == null)
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "PUTExploration",
                                         "Return, not current PUT method is set");
                WriteStopStatus();
                return;
            }

            SafeDebug.AssertNotNull(this.pmd.CurrentPUTMethod, "CurrentPUTMethod should be set by this time");
            var currPUTSignature = MethodOrFieldAnalyzer.GetMethodSignature(this.pmd.CurrentPUTMethod);

            if (this.pmd.AllExploredMethods.Contains(currPUTSignature))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "PUTExploration",
                                         "Ignoring the post processing of the PUT " + currPUTSignature + " since it is explored earlier!!!");
                WriteStopStatus();
                return;
            }

            //Add this to pending methods
            PexMePostProcessor ppp = new PexMePostProcessor(host);

            ppp.AfterExecution();
        }
        /// <summary>
        /// Given a uncovered code location and the associated terms, this
        /// method infers factory method for that code location.
        ///
        /// Assumes that the uncovered branch is mainly due to an object creating issue
        /// </summary>
        /// <returns></returns>
        public bool TryInferFactoryMethod(UncoveredCodeLocationStore ucls, out SafeSet <Method> suggestedMethods)
        {
            SafeDebug.AssumeNotNull(ucls, "ucls");

            if (ucls.AllFields.Count == 0)
            {
                this.host.Log.LogError(WikiTopics.MissingWikiTopic, "factoryguesser",
                                       "No information about involving fields in the uncovered branch");
                suggestedMethods = null;
                return(false);
            }

            //Check whether the feature is currently supported
            FieldModificationType fmt = this.GetRequiredFieldModificationType(ucls);

            if (!(fmt == FieldModificationType.NON_NULL_SET ||
                  fmt == FieldModificationType.NULL_SET || fmt == FieldModificationType.INCREMENT || fmt == FieldModificationType.DECREMENT ||
                  fmt == FieldModificationType.FALSE_SET || fmt == FieldModificationType.TRUE_SET))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Format " + fmt.ToString() + " is not supported for suggesting factory methods");
                suggestedMethods = null;
                return(false);
            }

            //Step 1: Get the exact type whose factory method is required for covering this branch.
            //Decided based on where there is a subsequent field which can be directly handled rather than the top field.
            //This step is moved to the place where the uncovered location is initially stored

            //Step 2: Decide which methods of this type should be invoked. Use a bottomup approach
            //for inferrinfg the exact method
            if (!this.GetTargetMethod(ucls, ucls.TargetField, out suggestedMethods))
            {
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                         "Failed to retrieve the target method of field " + ucls.TargetField.FullName + " in type " + ucls.ExplorableType.FullName);
                suggestedMethods = null;
                return(false);
            }

            var sb = new StringBuilder();

            foreach (var m in suggestedMethods)
            {
                sb.AppendLine(MethodOrFieldAnalyzer.GetMethodSignature(m));
            }
            ucls.SuggestedMethodsforFactory = sb.ToString();

            //Create a factory suggestion store. This is expected by the rest of the code.
            FactorySuggestionStore fss;

            if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucls.ExplorableType.ToString(), out fss))
            {
                fss = new FactorySuggestionStore();
                fss.DeclaringType = ucls.ExplorableType.ToString();
                this.pmd.FactorySuggestionsDictionary[ucls.ExplorableType.ToString()] = fss;
            }

            return(true);
        }
예제 #9
0
 /// <summary>
 /// Adds a field entity
 /// </summary>
 /// <param name="fd"></param>
 public void AddFieldEntity(TypeDefinition td, FieldDefinition fd)
 {
     if (!fieldEntities.ContainsKey(fd.FullName))
     {
         var             field = fd.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(this.host, td));
         DeclFieldEntity dfe   = new DeclFieldEntity(field);
         fieldEntities[field.FullName] = dfe;
     }
 }
예제 #10
0
 /// <summary>
 /// Adds a declared entity. Returns either the existing one or creates a new one
 /// </summary>
 /// <param name="de"></param>
 public void AddToDeclEntityDic(TypeDefinition td, out DeclClassEntity dce)
 {
     if (!this.declEntityDic.TryGetValue(td.FullName, out dce))
     {
         TypeEx type = td.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(this.Host, td));
         dce = new DeclClassEntity(type);
         declEntityDic[type.FullName] = dce;
     }
 }
예제 #11
0
        /// <summary>
        /// Collects all definitions and uses among each class in the assembly under analysis
        /// </summary>
        /// <param name="ade"></param>
        private static void CollectAllDefsAndUsesInTypeDef(TypeDefinition td, DeclClassEntity ade)
        {
            var             host = DUCoverStore.GetInstance().Host;
            SideEffectStore ses  = SideEffectStore.GetInstance();
            var             psd  = host.GetService <PexMeStaticDatabase>() as PexMeStaticDatabase;

            foreach (var constructor in td.DeclaredInstanceConstructors)
            {
                var method = constructor.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(host, td),
                                                     MethodOrFieldAnalyzer.GetGenericMethodParameters(host, constructor));
                CollectDefsAndUsesInMethod(psd, td, ade, method, null, ses);
            }

            foreach (var mdef in td.DeclaredInstanceMethods)
            {
                try
                {
                    var method = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(host, td),
                                                  MethodOrFieldAnalyzer.GetGenericMethodParameters(host, mdef));
                    CollectDefsAndUsesInMethod(psd, td, ade, method, null, ses);
                }
                catch (Exception ex)
                {
                    logger.ErrorException("Failed to instantiate method " + mdef.FullName, ex);
                }
            }

            foreach (var prop in td.DeclaredProperties)
            {
                var getter = prop.Getter;
                if (getter != null)
                {
                    Field usedField;
                    int   foffset;
                    var   method = getter.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(host, td),
                                                      MethodOrFieldAnalyzer.GetGenericMethodParameters(host, getter));
                    if (TryGetFieldOfGetter(method, out usedField, out foffset))
                    {
                        DeclFieldEntity dfe;
                        if (ade.FieldEntities.TryGetValue(usedField.FullName, out dfe))
                        {
                            //Found an accessor. register the usage
                            dfe.AddToUseList(method, foffset);
                        }
                    }
                }

                var setter = prop.Setter;
                if (setter != null)
                {
                    var method = setter.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(host, td),
                                                    MethodOrFieldAnalyzer.GetGenericMethodParameters(host, setter));
                    CollectDefsAndUsesInMethod(psd, td, ade, method, null, ses);
                }
            }
        }
예제 #12
0
 /// <summary>
 /// Generates nested command files. Ignores if there are any PUTs in
 /// pmd.PendingExplorationMethods since those methods can cause cycles.
 /// </summary>
 /// <param name="allSuggestedNewPUTs"></param>
 /// <param name="cmdfile"></param>
 private void GenerateNestedCommandFile(SafeSet <Method> allSuggestedNewPUTs, string cmdfile)
 {
     using (StreamWriter sw = new StreamWriter(cmdfile))
     {
         foreach (var newput in allSuggestedNewPUTs)
         {
             var newputsig = MethodOrFieldAnalyzer.GetMethodSignature(newput);
             sw.WriteLine(PUTGenerator.PUTGenerator.GeneratePUTCommand(newput));
         }
     }
 }
예제 #13
0
        GetPersistentFieldDictionary(SafeDictionary <Field, FieldStore> fielddic)
        {
            var pfielddic = new System.Collections.Generic.Dictionary <string, PersistentFieldStore>();

            foreach (var field in fielddic.Keys)
            {
                var fieldstr = MethodOrFieldAnalyzer.GetPersistentStringFormOfField(field);
                PersistentFieldStore pfs;
                bool bresult = PersistentFieldStore.TryGetPersistentFieldStore(this.host, fielddic[field], out pfs);
                SafeDebug.Assume(bresult, "Failed to get persistent field store!!!");
                pfielddic[fieldstr] = pfs;
            }
            return(pfielddic);
        }
예제 #14
0
            public OrderedMethodEffects(IPexComponent host, Method method)
            {
                SafeDebug.AssumeNotNull(method, "method");
                this.Method = method;

                TypeEx declaringType;

                if (!method.TryGetDeclaringType(out declaringType))
                {
                    //TODO: error
                }

                MethodOrFieldAnalyzer.TryComputeMethodEffects(host, declaringType, method, null, out this.Effects);
            }
예제 #15
0
        /// <summary>
        /// Checks whether there are any looping requireements based on looping threshold and enhances
        /// the sequence accordingly. Applies only for INCREMENT and DECREMENT field modification types
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="p"></param>
        private void CheckNEnhanceForLooping(PersistentUncoveredLocationStore pucls,
                                             int fitnessval, FieldModificationType fmt, SafeList <Field> culpritFields)
        {
            if (fmt != FieldModificationType.INCREMENT && fmt != FieldModificationType.DECREMENT)
            {
                return;
            }

            //Not even a single execution happened on this location.
            if (fitnessval == Int32.MaxValue)
            {
                return;
            }

            var        field = culpritFields[0];
            FieldStore fs;

            if (!this.pmd.FieldDictionary.TryGetValue(field, out fs))
            {
                return;
            }

            Dictionary <string, Method> writeMethods = new Dictionary <string, Method>();

            foreach (var mset in fs.WriteMethods.Values)
            {
                foreach (var m in mset)
                {
                    var sig = MethodOrFieldAnalyzer.GetMethodSignature(m);
                    writeMethods.Add(sig, m);
                }
            }

            foreach (var seq in pucls.SuggestedMethodSequences)
            {
                string loop_method;
                if (!this.IsEligibleForLooping(seq, field, writeMethods, fs, out loop_method))
                {
                    continue;
                }

                pucls.LoopingFeatureApplied = true;
                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "LoopingFeature",
                                         "Applying looping feature on method: " + loop_method + " (" + (fitnessval - 1) + ")");
                for (int count = 1; count < fitnessval; count++)
                {
                    seq.Sequence.Add(loop_method);
                }
            }
        }
예제 #16
0
        GetPersistentMethodDictionary(SafeDictionary <Method, MethodStore> methoddic)
        {
            var pmethoddic = new System.Collections.Generic.Dictionary <string, PersistentMethodStore>();

            foreach (var method in methoddic.Keys)
            {
                var methodstr = MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(method);
                PersistentMethodStore pms;
                bool bresult = PersistentMethodStore.TryGetPersistentMethodStore(methoddic[method], out pms);
                SafeDebug.Assume(bresult, "Failed to get persistent method store!!!");
                pmethoddic[methodstr] = pms;
            }

            return(pmethoddic);
        }
        /// <summary>
        /// Function the retrieves associated Persistent store for each MethodStore
        /// </summary>
        /// <param name="ms"></param>
        /// <param name="pms"></param>
        /// <returns></returns>
        public static bool TryGetPersistentFieldStore(IPexComponent host, FieldStore fs, out PersistentFieldStore pfs)
        {
            pfs = new PersistentFieldStore();

            pfs.FieldName = MethodOrFieldAnalyzer.GetPersistentStringFormOfField(fs.FieldName);
            //foreach(var value in fs.FieldValues)
            //    pfs.FieldValues.Add(value);

            //TODO: Performance can be improved via caching over here
            foreach (var m in fs.ReadMethods)
            {
                pfs.ReadMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(m));
            }

            foreach (var typeex in fs.WriteMethods.Keys)
            {
                HashSet <string> wmethods = new HashSet <string>();
                pfs.WriteMethods.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfTypeEx(typeex), wmethods);

                SafeSet <Method> methods;
                bool             bresult = fs.WriteMethods.TryGetValue(typeex, out methods);
                SafeDebug.Assume(bresult, "Failed to get associated set of methods for a type");

                var assemblyname = typeex.Definition.Module.Assembly.Location;
                var typename     = typeex.FullName;

                foreach (var m in methods)
                {
                    wmethods.Add(assemblyname + PexMeConstants.PexMePersistenceFormSeparator
                                 + typename + PexMeConstants.PexMePersistenceFormSeparator + MethodOrFieldAnalyzer.GetMethodSignature(m));
                }
            }

            foreach (var m in fs.ModificationTypeDictionary.Keys)
            {
                var value = fs.ModificationTypeDictionary[m];
                pfs.ModificationTypeDictionary.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(m), value);
            }

            foreach (var m in fs.PreciseModificationTypeDictionary.Keys)
            {
                var value = fs.PreciseModificationTypeDictionary[m];
                pfs.PreciseModificationTypeDictionary.Add(MethodOrFieldAnalyzer.GetPersistentStringFormOfMethod(m), value);
            }

            return(true);
        }
예제 #18
0
        private static SafeDictionary <Field, FieldStore> GetFieldDictionary(IPexComponent host,
                                                                             System.Collections.Generic.Dictionary <string, PersistentFieldStore> pfielddic)
        {
            var fielddic = new SafeDictionary <Field, FieldStore>();

            foreach (var fieldstr in pfielddic.Keys)
            {
                Field field;
                bool  bresult = MethodOrFieldAnalyzer.TryGetFieldFromPersistentStringForm(host, fieldstr, out field);
                SafeDebug.Assume(bresult, "Failed to get field from persistent store!!!");

                FieldStore fs;
                bresult = PersistentFieldStore.TryGetFieldStore(host, pfielddic[fieldstr], out fs);
                SafeDebug.Assume(bresult, "Failed to get field store!!!");

                fielddic[field] = fs;
            }
            return(fielddic);
        }
예제 #19
0
        /// <summary>
        /// Gets a MethodSignatureSequenceList for each putmethod. If one does not exist,
        /// creates a fresh one
        /// </summary>
        /// <param name="putmethod"></param>
        /// <returns></returns>
        public bool TryGetListFromFinalSuggestedSequences(Method putmethod, out MethodSignatureSequenceList mssl)
        {
            mssl = null;

            Method assocMethod;

            if (!PUTGenerator.PUTGenerator.TryRetrieveMethodCall(putmethod, out assocMethod))
            {
                return(false);
            }

            var methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out mssl))
            {
                mssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, mssl);
            }
            return(true);
        }
예제 #20
0
        public PersistentUncoveredLocationStore(CodeLocation cl,
                                                TypeEx explorableType, int termIndex, int fitnessvalue, FactorySuggestionStore fss)
        {
            this.CodeLocation    = cl.ToString();
            this.MethodSignature = MethodOrFieldAnalyzer.GetMethodSignature(cl.Method);
            TypeDefinition declaringType;

            if (!cl.Method.TryGetDeclaringType(out declaringType))
            {
                //TODO:Error
            }

            this.ExplorableType    = explorableType.ToString();
            this.Offset            = cl.Offset;
            this.AssemblyShortName = declaringType.Module.Assembly.Location;
            this.declaringTypeStr  = declaringType.ToString();
            this.Fitnessvalue      = fitnessvalue;
            this.TermIndex         = termIndex;
            this.parentfss         = fss;
        }
        /// <summary>
        /// Parses each record and stores into internal dictionary
        /// </summary>
        /// <param name="assemblyname"></param>
        /// <param name="typename"></param>
        /// <param name="fieldname"></param>
        /// <param name="fmttype"></param>
        /// <param name="methodname"></param>
        private static void ParseRecord(IPexComponent host, string assemblyname, string typename, string fieldname, string fmttype, string methodname)
        {
            Field field;

            if (!MethodOrFieldAnalyzer.TryGetField(host, assemblyname, typename, fieldname, out field))
            {
                host.Log.LogWarning(WikiTopics.MissingWikiTopic, "PredefinedEffects", "Failed to load field: " + fieldname);
                return;
            }

            FieldModificationType fmt = FieldStore.GetModificationTypeFromString(fmttype);

            Method method;

            if (!MethodOrFieldAnalyzer.TryGetMethod(host, assemblyname, typename, methodname, out method))
            {
                host.Log.LogWarning(WikiTopics.MissingWikiTopic, "PredefinedEffects", "Failed to load method: " + methodname);
                return;
            }

            //storing into the effects store
            PreDefinedMethodEffectsStore pdme = new PreDefinedMethodEffectsStore(field, fmt);
            List <Method> suggestedMethods;
            PreDefinedMethodEffectsStore existingPdme;

            if (!effectsStore.TryGetValue(pdme, out existingPdme))
            {
                suggestedMethods         = new List <Method>();
                pdme.suggestedmethodList = suggestedMethods;
                effectsStore.Add(pdme, pdme);
            }
            else
            {
                suggestedMethods = existingPdme.suggestedmethodList;
            }

            suggestedMethods.Add(method);
        }
예제 #22
0
        /// <summary>
        /// Dumps the graph to an XML file
        /// </summary>
        /// <param name="filename"></param>
        public void DumpToXMLFile(StreamWriter sw)
        {
            sw.WriteLine("\t<cfg methodName=\"" + MethodOrFieldAnalyzer.GetMethodSignature(this.method) + "\">");

            //dumping vertices
            sw.WriteLine("\t<vertices>");
            StringBuilder edgeSb = new StringBuilder("\t<edges>\r\n");

            if (this.rootVertex != null)
            {
                sw.WriteLine("\t\t<vertex id=\"" + this.rootVertex.Instruction.Offset + "\" kind=\"Entry\" offset=\"" + this.rootVertex.Instruction.Offset + "\"></vertex>");
                foreach (var vertex in this.vertices.Values)
                {
                    if (vertex != this.rootVertex)
                    {
                        sw.WriteLine("\t\t<vertex id=\"" + vertex.Instruction.Offset + "\" kind=\"Normal\" offset=\"" + vertex.Instruction.Offset + "\"></vertex>");
                    }

                    //add edges of this vertex to the edge string
                    foreach (var outedge in this.vertexOutEdges[vertex])
                    {
                        var sourceVertex = outedge.Source as InstructionVertex;
                        var targetVertex = outedge.Target as InstructionVertex;

                        edgeSb.Append("\t\t<edge sourceid=\"" + sourceVertex.Instruction.Offset + "\" targetid=\"" + targetVertex.Instruction.Offset + "\"></edge>\r\n");
                    }
                }
            }

            sw.WriteLine("\t</vertices>");

            edgeSb.Append("\t</edges>\n");

            //dumping edges
            sw.WriteLine(edgeSb.ToString());
            sw.WriteLine("\t</cfg>");
        }
예제 #23
0
        /// <summary>
        /// Method is allowed to be invoked only once. Therefore the order of loading classes into the Dictionary is
        /// quite important.
        /// </summary>
        /// <param name="host"></param>
        public static bool LoadPredefinedGenericClasses(IPexComponent host, string assemblyName)
        {
            //QuickGraph: TEdge -> Edge<int>
            TypeEx edgeTypeEx;
            PreDefinedGenericClassesStore tedgePdgc = new PreDefinedGenericClassesStore();

            predefinedClasses.Add("TEdge", tedgePdgc);
            if (MethodOrFieldAnalyzer.TryGetTypeExFromName(host, assemblyName, "QuickGraph.Edge`1", out edgeTypeEx))
            {
                tedgePdgc.AddToPredinedStore("QuickGraph.AdjacencyGraph`2", edgeTypeEx);
                tedgePdgc.AddToPredinedStore("QuickGraph.IGraph`2", edgeTypeEx);
            }

            //Dsa: TNode for BinarySearchTree -> Dsa.DataStructures.BinaryTreeNode`1
            PreDefinedGenericClassesStore tnodePdgc = new PreDefinedGenericClassesStore();

            predefinedClasses.Add("TNode", tnodePdgc);
            TypeEx binNodeEx;

            if (MethodOrFieldAnalyzer.TryGetTypeExFromName(host, assemblyName, "Dsa.DataStructures.BinaryTreeNode`1", out binNodeEx))
            {
                tnodePdgc.AddToPredinedStore("Dsa.DataStructures.BinarySearchTree`1", binNodeEx);
                tnodePdgc.AddToPredinedStore("Dsa.DataStructures.CommonBinaryTree`2", binNodeEx);
                tnodePdgc.AddToPredinedStore("System.Collections.Generic.Queue`1", binNodeEx);
            }

            TypeEx avltreeNodeEx = null;

            if (MethodOrFieldAnalyzer.TryGetTypeExFromName(host, assemblyName, "Dsa.DataStructures.AvlTreeNode`1", out avltreeNodeEx))
            {
                tnodePdgc.AddToPredinedStore("Dsa.DataStructures.AvlTree`1", avltreeNodeEx);
                tnodePdgc.AddToPredinedStore("Dsa.DataStructures.CommonBinaryTree`2", avltreeNodeEx);
                tnodePdgc.AddToPredinedStore("System.Collections.Generic.Queue`1", avltreeNodeEx);
            }

            return(true);
        }
예제 #24
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);
                    }
                }
            }
        }
예제 #25
0
        /// <summary>
        /// Updates all sequences in uncovered location stores with new suggestions that
        /// are also stored within the PUT itself
        /// </summary>
        private void UpdateUncoveredLocationsWithNewSuggestions(string currPUTSignature)
        {
            //Iterate through each uncovered location
            foreach (var ucovLocList in this.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;
                if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "UncoveredLocations",
                                             "Failed to retrieve factory suggestion store for explorable type " + ucovLocList.ExplorableType);
                    continue;
                }

                MethodSignatureSequenceList putspecificlist;
                if (!fss.FinalPUTSequences.TryGetValue(currPUTSignature, out putspecificlist))
                {
                    putspecificlist = new MethodSignatureSequenceList();
                }

                var ucovLoc = ucovLocList.StoreList[0];
                //If a suggested method is not yet explored, add it to all new suggested method
                if (ucovLoc.SuggestedMethodSetforFactory != null)
                {
                    //Prepare new sequences with the suggested method
                    var newmssl = new MethodSignatureSequenceList();
                    foreach (var suggestedm in ucovLoc.SuggestedMethodSetforFactory)
                    {
                        //Get all the pre-requisite sequences for this suggested method
                        var suggestedmsig = MethodOrFieldAnalyzer.GetMethodSignature(suggestedm);
                        MethodSignatureSequenceList mssl;
                        fss.FinalSuggestedMethodSequences.TryGetValue(suggestedmsig, out mssl);
                        if (mssl == null || mssl.SequenceList.Count == 0)
                        {
                            var tempmss = new MethodSignatureSequence();
                            tempmss.Sequence.Add(suggestedmsig);
                            newmssl.SequenceList.Add(tempmss);
                        }
                        else
                        {
                            //Make a new sequence from the suggested method and its pre-requisite
                            foreach (var seq in mssl.SequenceList)
                            {
                                var tempmss = new MethodSignatureSequence();
                                tempmss.Sequence.AddRange(seq.Sequence);
                                tempmss.Sequence.Add(suggestedmsig);
                                newmssl.SequenceList.Add(tempmss);
                            }
                        }
                    }

                    //Add all these suggestions to the uncovered location store itself
                    bool bNewlyCreated = false;
                    var  pucls         = fss.GetPersistentLocationstore(ucovLoc, out bNewlyCreated);
                    pucls.UpdateSuggestedMethodSequences(newmssl, putspecificlist);

                    //Check whether any looping is required. If a method
                    //is repeated more than 3 times, in a sequence, we consider
                    //it as a looping requirement. This is only a heuristic based.
                    if (!PexMeConstants.IGNORE_LOOP_FEATURE && !pucls.LoopingFeatureApplied)
                    {
                        this.CheckNEnhanceForLooping(pucls, pucls.Fitnessvalue,
                                                     ucovLoc.DesiredFieldModificationType, ucovLoc.AllFields);
                    }

                    //Check for the number of sequences in this pucls. If they
                    //exceed the limit, delete the sequences
                    if ((pucls.SuggestedMethodSequences.Count - fss.FinalSuggestedMethodSequences.Values.Count)
                        > PexMeConstants.MAX_ALLOWED_SEQUENCES)
                    {
                        fss.RemoveUncoveredLocationStore(pucls, false, this.pmd);
                        var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);
                        fss.PermanentFailedUncoveredLocations.Add(key);
                        fss.TemporaryFailedUncoveredLocations.Add(key, PexMeConstants.MAX_UNCOVEREDLOC_ATTEMPTS);
                        this.pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "uncoveredlocation",
                                                @"Sequences for uncovered location " + pucls.CodeLocation +
                                                "crossed the threshold " + PexMeConstants.MAX_ALLOWED_SEQUENCES + ", Deleted forever");
                    }
                }
            }

            //Add default sequences to the newly created factory suggestion stores
            foreach (var ucovLocList in this.pmd.UncoveredLocationDictionary.Values)
            {
                if (ucovLocList.StoreList.Count == 0)
                {
                    continue;
                }

                FactorySuggestionStore fss;
                if (!this.pmd.FactorySuggestionsDictionary.TryGetValue(ucovLocList.ExplorableType, out fss))
                {
                    continue;
                }

                var ucovLoc = ucovLocList.StoreList[0];
                if (fss.BCreatedNow)
                {
                    fss.BCreatedNow = false;
                    var mss            = new MethodSignatureSequence();
                    var explorableType = ucovLocList.ExplorableType;
                    foreach (var methodinucov in ucovLoc.MethodCallSequence.Sequence)
                    {
                        if (methodinucov.Contains("..ctor(")) //Don't add constructors
                        {
                            continue;
                        }
                        if (!methodinucov.Contains(explorableType)) //Ignore the method calls from other types
                        {
                            continue;
                        }
                        mss.Sequence.Add(methodinucov);
                    }
                    fss.AddDefaultSequence(this.pmd, mss);
                }
            }
        }
예제 #26
0
        /// <summary>
        /// Get the exact type whose factory method is required for covering this branch.
        /// Decided based on where there is a subsequent field which can be directly handled
        /// rather than the top field. The primary objective is to minimize the search space
        /// as much as possible.
        /// </summary>
        /// <param name="ucls"></param>
        /// <param name="targetField"></param>
        /// <returns></returns>
        public static bool GetTargetExplorableField(IPexComponent host, SafeList <Field> allFields, out Field targetField, out TypeEx declaringType)
        {
            targetField = null;
            var allInvolvedFields = new SafeList <Field>();

            allInvolvedFields.AddRange(allFields);

            int numFields = allInvolvedFields.Count;

            if (numFields == 1)
            {
                targetField = allInvolvedFields[0];
                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(host, targetField, out declaringType))
                {
                    declaringType = null;
                    return(false);
                }
                return(true);
            }

            allInvolvedFields.Reverse();

            //Commenting the following functionality, which is actually intended
            //for reducing the enormous search space in the list of fields. However,
            //since our approach is not using the Pex's default factory method mechanism
            //this may not be of any use.
            //TypeEx prevFieldType = null;
            //for (int count = 0; count < allInvolvedFields.Count; count++)
            //{
            //    var currentField = allInvolvedFields[count];

            //    if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeDefinition(host, currentField, out declaringType))
            //    {
            //        host.Log.LogError(WikiTopics.MissingWikiTopic, "targetfield",
            //            "Failed to get the declaring type for the field " + currentField.FullName);
            //        return false;
            //    }

            //    SafeDebug.Assume(prevFieldType == null || prevFieldType == declaringType || prevFieldType.IsAssignableTo(declaringType)
            //        || declaringType.IsAssignableTo(prevFieldType),
            //        "The current field type (" + declaringType + ") should be the same as the previous field type (" + prevFieldType + ")");

            //    if (MethodOrFieldAnalyzer.IsFieldExternallyVisible(host, declaringType, currentField))
            //    {
            //        prevFieldType = currentField.Type;
            //        continue;
            //    }
            //    else
            //    {
            //        targetField = currentField;
            //        return true;
            //    }
            //}

            targetField = allInvolvedFields[0];
            if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(host, targetField, out declaringType))
            {
                host.Log.LogError(WikiTopics.MissingWikiTopic, "targetfield",
                                  "Failed to get the declaring type for the field " + targetField.FullName);
                return(false);
            }
            return(true);
        }
예제 #27
0
        /// <summary>
        /// Gets the target method that need to be invoked for setting a field.
        /// Based on static analysis and later uses dynamic analysis for giving
        /// more priority to those methods that are identified through dynamic analysis also.
        /// </summary>
        /// <param name="ucls"></param>
        /// <param name="targetField"></param>
        /// <param name="declaringType"></param>
        /// <param name="targetMethods"></param>
        /// <returns></returns>
        private bool GetTargetMethod(UncoveredCodeLocationStore ucls, Field targetField,
                                     out SafeSet <Method> targetMethods)
        {
            targetMethods = new SafeSet <Method>();

            int numfields = ucls.AllFields.Count;

            for (int count = 0; count < numfields; count++)
            {
                var field = ucls.AllFields[count];

                //Get all write methods for this field
                SafeSet <Method> writeMethods = null;

                //Get the declaring type of the field. There are two possibilities of choosing
                //a declaring type: from the next field or the enclosing type
                TypeEx declaringType1 = null, declaringType2 = null;

                //If there is a parent field, the declaring type should
                //be upgraded to the type of the next field in the list, which could be
                //a sub-class of the actual declaring type
                if (count < numfields - 1)
                {
                    var nextField = ucls.AllFields[count + 1];
                    declaringType1 = nextField.Type;
                }

                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeEx(this.host, field, out declaringType2))
                {
                    SafeDebug.AssumeNotNull(declaringType2, "declaringType");
                }

                var declaringType = declaringType2;
                if (declaringType1 != null && declaringType1 != declaringType2)
                {
                    declaringType = this.ChooseADeclaringType(declaringType1, declaringType2);
                }

                //Chosen declaringType should be a part of all field types stored
                //in UCLS. If not, there can be inheritance issues
                if (!ucls.AllFieldTypes.Contains(declaringType))
                {
                    //Find out the type to which declaringType is assignable and update it
                    foreach (var tex in ucls.AllFieldTypes)
                    {
                        if (tex.IsAssignableTo(declaringType))
                        {
                            declaringType = tex;
                            break;
                        }
                    }
                }

                //For the first field, get all the methods that modify the field
                //using static analysis
                if (targetMethods.Count == 0)
                {
                    //Try from static analysis store
                    if (!this.psd.TryGetFilteredWriteMethods(field, declaringType, ucls.DesiredFieldModificationType, out writeMethods))
                    {
                        this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                 "Failed to get write methods for the field " + field.FullName);
                        return(false);
                    }

                    //Try from dynamic analysis
                    //if (!this.pmd.FieldDictionary.TryGetValue(field.GlobalIndex, out fs))
                    targetMethods.AddRange(writeMethods);
                }
                else
                {
                    //Get the callers of all methods in targetmethods
                    SafeSet <Method> callerMethods = new SafeSet <Method>();
                    foreach (var tmw in targetMethods)
                    {
                        SafeSet <Method> callingMethods;

                        //TODO: Performance improvements can be done here as we repeat the loops inside
                        //the method for each method in targetMethods
                        if (!this.psd.TryGetCallingMethodsInType(tmw, field, declaringType, out callingMethods))
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                     SafeString.Format("Failed to get calling methods of {0} through static and dynamic analysis", tmw));
                            continue;
                        }

                        //Filter the called methods based on field to avoid
                        //unnecessary additional methods
                        SafeSet <Method> subcallingMethods = this.psd.FilterCallingMethodsBasedOnField(tmw, field, callingMethods);
                        if (callingMethods.Count > 0 && subcallingMethods.Count == 0)
                        {
                            this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "callingmethods",
                                                     "Failed to filter calling methods based on field, adding all methods");
                            subcallingMethods.AddRange(callingMethods);
                        }

                        //Check in dynamic analysis portion
                        //if (!this.pmd.MethodDictionary.TryGetValue(tmw.GlobalIndex, out mstore))
                        //{
                        //}
                        //else
                        //    callingMethods = mstore.CallingMethods[declaringType];

                        callerMethods.AddRange(subcallingMethods);
                    }

                    //All caller methods in the parent type
                    targetMethods = callerMethods;
                }

                //Our objective is to search for the methods that belong to our target field.
                //Stop traversal once the desired method is found
                if (field == targetField)
                {
                    break;
                }
            }

            return(true);
        }
예제 #28
0
        /// <summary>
        /// Gets invoked after the execution of the entire pex process
        /// </summary>
        public void AfterExecution()
        {
            try
            {
                //this.host.Log.LogMessage(PexMeLogCategories.MethodBegin, "Begin of PexMePostProcessor.AfterExecution() method");

                DirectoryHelper.CheckExistsOrCreate(PexMeConstants.PexMeStorageDirectory);

                //Filter covered locations from uncovered locations
                this.pmd.FilterOutCoveredCodeLocations();
                var currPUTSignature = MethodOrFieldAnalyzer.GetMethodSignature(this.pmd.CurrentPUTMethod);

                //Suggest factory methods
                SafeSet <Method> allSuggestedNewPUTs;
                bool             bHasSomeCoveredLocation, bAllAreNewLocations, bNoneAreNewLocations;
                this.GuessFactorymethods(out allSuggestedNewPUTs, currPUTSignature, out bHasSomeCoveredLocation, out bAllAreNewLocations, out bNoneAreNewLocations);

                var filename = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.ReExecutionStatusFile);
                using (StreamWriter sw = new StreamWriter(filename))
                {
                    //nestingdepth == null represents that this is not run from the Perl
                    //script. So, ignoring the generation of alternative PUTs.
                    if (allSuggestedNewPUTs.Count == 0 || this.ndepth == -1 ||
                        this.ndepth >= PexMeConstants.MAX_ALLOWED_NESTED_DEPTH)
                    {
                        this.pmd.PendingExplorationMethods.Remove(currPUTSignature);

                        //Decide to re-execute or stop. So update all sequences
                        //within uncovered locations with new suggestions and prepare for re-execute
                        this.UpdateUncoveredLocationsWithNewSuggestions(currPUTSignature);

                        //Check whether there is a need to further continue based on requirement
                        //in uncovered locations in factory suggestion store. Used to communicate to outside
                        //process for re-execution
                        if (this.pmd.NeedReExecute(bHasSomeCoveredLocation, bAllAreNewLocations, bNoneAreNewLocations))
                        {
                            sw.WriteLine("REEXECUTE");
                        }
                        else
                        {
                            sw.WriteLine("STOP");

                            //Marks a successful exploration of this PUT
                            this.pmd.AllExploredMethods.Add(currPUTSignature);

                            //Remove all PUT specific sequences from the permanent store
                            this.EndOfPUTCleanUp(currPUTSignature);
                        }
                    }
                    else
                    {
                        //Set up new targets for additional explorations which are required for achieving
                        //the current target.
                        var newCommandFile = "PexMe." + System.Environment.TickCount + ".txt";
                        this.GenerateNestedCommandFile(allSuggestedNewPUTs, newCommandFile);
                        sw.WriteLine("NESTEDEXECUTE");
                        sw.WriteLine(newCommandFile);

                        //Putting all current information on uncovered locations to dormant
                        //stage. Will be re-activated when required and when this PUT is again
                        //brought to action.
                        var currPUT = MethodOrFieldAnalyzer.GetMethodSignature(this.pmd.CurrentPUTMethod);
                        this.SendToDormant(currPUT);
                    }
                }

                this.pdw.DumpDynamicDatabase(this.pmd as PexMeDynamicDatabase);
                this.pdw.DumpStaticDatabase(this.psd as PexMeStaticDatabase);
            }
            catch (Exception ex)
            {
                this.host.Log.LogCriticalFromException(ex, WikiTopics.MissingWikiTopic,
                                                       "postprocessor", ex.StackTrace);
            }
        }
예제 #29
0
        /// <summary>
        /// Removes the uncovered location store. Mainly keeps the sequence
        /// that helped to cover the target location and drops all others
        /// </summary>
        /// <param name="pucls"></param>
        /// <param name="successful">Helps to distinguish between a removal during success and failure</param>
        internal void RemoveUncoveredLocationStore(PersistentUncoveredLocationStore pucls,
                                                   bool successful, PexMeDynamicDatabase pmd)
        {
            var key = UncoveredCodeLocationStore.GetKey(pucls.CodeLocation, pucls.ExplorableType, pucls.TermIndex);

            this.locationStoreSpecificSequences.Remove(key);
            if (!successful)
            {
                return;
            }

            this.SuccessfulCoveredLocations.Add(key);
            this.PermanentFailedUncoveredLocations.Remove(key);
            this.TemporaryFailedUncoveredLocations.Remove(key);
            this.UncoveredSystemLibLocations.Remove(key);

            //Get the method associated with the current exploring PUT
            string methodcallname = PexMeConstants.DEFAULT_FINAL_SUGGESTION_STORE;
            Method assocMethod;

            if (PUTGenerator.PUTGenerator.TryRetrieveMethodCall(pmd.CurrentPUTMethod, out assocMethod))
            {
                methodcallname = MethodOrFieldAnalyzer.GetMethodSignature(assocMethod);
            }

            //Get PUT independent sequence list
            MethodSignatureSequenceList putIndependentMssl;

            if (!this.FinalSuggestedMethodSequences.TryGetValue(methodcallname, out putIndependentMssl))
            {
                putIndependentMssl = new MethodSignatureSequenceList();
                this.FinalSuggestedMethodSequences.Add(methodcallname, putIndependentMssl);
            }

            //Also update the PUT specific sequences. These gets cleared once a
            //PUT is completely explored.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList putSpecificMssl;

            if (!this.FinalPUTSequences.TryGetValue(putsignature, out putSpecificMssl))
            {
                putSpecificMssl = new MethodSignatureSequenceList();
                this.FinalPUTSequences.Add(putsignature, putSpecificMssl);
            }

            //Any Persistent Uncovered location store that is successfully
            //covered gets a hit sequence
            SafeDebug.AssumeNotNull(pucls.HitSequence, "pucls.HitSequence");
            MethodSignatureSequence matchingseq;

            if (!FactorySuggestionStore.TryGetMatchingSequence(pucls.HitSequence,
                                                               pucls.SuggestedMethodSequences, out matchingseq))
            {
                //Failed to retrieve the hit sequence. However, a heuristic
                //can be used where there is only one suggested sequence
                if (pucls.SuggestedMethodSequences.Count == 1)
                {
                    matchingseq = pucls.SuggestedMethodSequences[0];
                    putIndependentMssl.Add(matchingseq);
                    putSpecificMssl.Add(matchingseq);
                }
                else
                {
                    pmd.Log.LogWarning(WikiTopics.MissingWikiTopic, "SequenceMatch",
                                       "Failed to retrieve a matching sequence for a hit sequence, adding complete hit sequence " + pucls.HitSequence);

                    var hitSubSequence = new MethodSignatureSequence();
                    foreach (var mhit in pucls.HitSequence.Sequence)
                    {
                        if (mhit.Contains("..ctor(")) //Don't add constructors
                        {
                            continue;
                        }
                        if (!mhit.Contains(this.DeclaringType)) //Ignore the method calls from other types
                        {
                            continue;
                        }
                        hitSubSequence.Sequence.Add(mhit);
                    }

                    //Add all sequences to final set of sequences for further usage.
                    putIndependentMssl.Add(hitSubSequence);
                    putSpecificMssl.Add(hitSubSequence);
                    //this.UpgradeActiveULStores(putsignature, pucls.SuggestedMethodSequences);
                }
            }
            else
            {
                //Add all sequences to final set of sequences for further usage.
                putIndependentMssl.Add(matchingseq);
                putSpecificMssl.Add(matchingseq);
                //this.UpgradeActiveULStores(putsignature, matchingseq);
            }
        }
예제 #30
0
        /// <summary>
        /// Gets the entire list of suggested methods
        /// </summary>
        /// <returns></returns>
        public IEnumerable <MethodSignatureSequence> GetSuggestedMethodSequences(PexMeDynamicDatabase pmd)
        {
            var uniqueSequenceList = new List <MethodSignatureSequence>();

            //Gather all sequences among all location stores. Detect the unique
            //sequences among them and suggest the complete unique sequences
            foreach (var pucls in this.locationStoreSpecificSequences.Values)
            {
                if (pucls.IsDormat())
                {
                    continue;
                }

                foreach (var ms in pucls.SuggestedMethodSequences)
                {
                    if (ms.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(ms))
                    {
                        uniqueSequenceList.Add(ms);
                    }
                }
            }

            //Return all final sequence ever collected to help cover more
            //at the first time itself. Along with the final suggested method,
            //we also need to add the method itself
            foreach (var methodid in this.FinalSuggestedMethodSequences.Keys)
            {
                var seqlist = this.FinalSuggestedMethodSequences[methodid];
                foreach (var seq in seqlist.SequenceList)
                {
                    MethodSignatureSequence tempseq = new MethodSignatureSequence();
                    tempseq.Sequence.AddRange(seq.Sequence);
                    tempseq.Sequence.Add(methodid);

                    if (!uniqueSequenceList.Contains(tempseq))
                    {
                        uniqueSequenceList.Add(tempseq);
                    }
                }
            }

            foreach (var seqlist in this.FinalSuggestedMethodSequences.Values)
            {
                foreach (var seq in seqlist.SequenceList)
                {
                    if (seq.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(seq))
                    {
                        uniqueSequenceList.Add(seq);
                    }
                }
            }

            //Return all previously collected sequences for this PUT, if there exist
            //no sequences specific to any uncovered location yet.
            var putsignature = MethodOrFieldAnalyzer.GetMethodSignature(pmd.CurrentPUTMethod);
            MethodSignatureSequenceList mssl;

            if (this.FinalPUTSequences.TryGetValue(putsignature, out mssl))
            {
                foreach (var seq in mssl.SequenceList)
                {
                    if (seq.Sequence.Count == 0)
                    {
                        continue;
                    }

                    if (!uniqueSequenceList.Contains(seq))
                    {
                        uniqueSequenceList.Add(seq);
                    }
                }
            }

            foreach (var ms in uniqueSequenceList)
            {
                yield return(ms);
            }
        }