예제 #1
0
        /// <summary>
        /// Retrieves the defined field
        /// </summary>
        /// <param name="method"></param>
        /// <param name="definedField"></param>
        /// <returns></returns>
        public static bool TryGetFieldOfSetter(Method method, out Field definedField)
        {
            SafeDebug.Assert(method.ShortName.StartsWith("set_"), "");
            definedField = null;
            MethodBodyEx body;

            if (!method.TryGetBody(out body) || !body.HasInstructions)
            {
                return(false);
            }

            int         offset = 0;
            Instruction instruction;
            OpCode      prevOpcode = OpCodes.Nop;

            while (body.TryGetInstruction(offset, out instruction))
            {
                SafeDebug.AssumeNotNull(instruction, "instruction");
                OpCode opCode = instruction.OpCode;
                if (opCode == OpCodes.Stfld || opCode == OpCodes.Stsfld)
                {
                    definedField = instruction.Field;
                    return(true);
                }
                offset = instruction.NextOffset;
            }

            return(false);
        }
예제 #2
0
            bool IPexAssumptionExceptionValidator.IsAssumption(Exception ex)
            {
                SafeDebug.AssumeNotNull(ex, "ex");

                // 1) must be a requires exception
                string trace;
                Type   exceptionType = ex.GetType();

                if (exceptionType == typeof(Cobra.Lang.RequireException) &&
                    ExceptionHelper.TryGetBestStackTrace(ex, out trace))
                {
                    StackTraceEx tx = host.Services.SymbolManager.ParseStackTrace(trace, true);

                    bool globalsFound = false;
                    for (int i = tx.Frames.Count - 1; i >= 0; i--)
                    {
                        StackFrameEx frame = tx.Frames[i];
                        if (frame.MethodName.StartsWith("require_"))
                        {
                            if (globalsFound) // already found? that's not good
                            {
                                return(false);
                            }
                            globalsFound = true;
                        }
                    }

                    return(globalsFound);
                }

                return(false);
            }
        public bool IsAssertMethod(MethodDefinition method, out int usefulParameters)
        {
            SafeDebug.AssumeNotNull(method, "method");
            TypeDefinition type;

            if (method.TryGetDeclaringType(out type))
            {
                if (type.SerializableName == MSTestv2TestFrameworkMetadata.AssertTypeDefinition)
                {
                    switch (method.ShortName)
                    {
                    case "IsFalse":
                    case "IsTrue":
                    case "IsNull":
                    case "IsNotNull":
                    case "IsInstanceOfType":
                    case "IsNotInstanceOfType":
                        usefulParameters = 1;
                        return(true);

                    case "AreEqual":
                    case "AreNotEqual":
                    case "AreSame":
                    case "AreNotSame":
                        usefulParameters = 2;
                        return(true);
                    }
                }
            }

            usefulParameters = -1;
            return(false);
        }
        /// <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);
        }
예제 #5
0
        /// <inheritdoc/>
        public override void EmitInconclusive(MethodBodyBuilder body, string message)
        {
            SafeDebug.AssumeNotNull(body, "body");

            body.Push(message);
            body.CallStatic(XunitTestFrameworkMetadata.Method_PexAssertInconclusive.Value);
            body.Statement();
        }
예제 #6
0
        /// <summary>
        /// Tries the get categories.
        /// </summary>
        /// <param name="element">
        /// The element.
        /// </param>
        /// <param name="names">
        /// The names.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        protected override bool TryGetCategories(ICustomAttributeProviderEx element, out IEnumerable <string> names)
        {
            SafeDebug.AssumeNotNull(element, "element");

            // TODO
            names = null;
            return(false);
        }
예제 #7
0
 public override bool TryMarkExpectedException(VisibilityContext visibility, MethodDefinitionBuilder method,
                                               Exception exception)
 {
     SafeDebug.AssumeNotNull(visibility, "visibility");
     SafeDebug.AssumeNotNull(method, "method");
     SafeDebug.AssumeNotNull(exception, "exception");
     return(false);
 }
예제 #8
0
        /// <inheritdoc/>
        public override void MarkTestMethod(PexExplorationBase exploration,
                                            IPexGeneratedTest test,
                                            MethodDefinitionBuilder method)
        {
            SafeDebug.AssumeNotNull(test, "test");
            SafeDebug.AssumeNotNull(method, "method");

            method.CustomAttributes.Add(new CustomAttributeBuilder(XunitTestFrameworkMetadata.Ctor_FactAttribute));
        }
예제 #9
0
        protected override object BeforeExploration <TAbstractValue>(IPexExplorationComponent <TAbstractValue> host)
        {
            SafeDebug.AssumeNotNull(host, "host");

            host.ExplorationServices.ExceptionManager.AddAssumptionExceptionValidator(
                new Validator <TAbstractValue>(host)
                );
            return(null);
        }
예제 #10
0
        /// <inheritdoc/>
        public override bool IsFixture(TypeDefinition target)
        {
            SafeDebug.AssumeNotNull(target, "target");

            return(!target.IsInterface &&
                   !target.IsEnumType &&
                   !target.IsAbstract &&
                   target.DeclaredVisibility == Visibility.Public &&
                   target.IsExported &&
                   target.GenericTypeParametersCount == 0);
        }
예제 #11
0
        /// <inheritdoc/>
        public override bool TryMarkOwner(MethodDefinitionBuilder method, string owner)
        {
            SafeDebug.AssumeNotNull(method, "method");
            SafeDebug.AssumeNotNull(owner, "owner");

            method.CustomAttributes.Add(new CustomAttributeBuilder(XunitTestFrameworkMetadata.Ctor_TraitAttribute,
                                                                   MetadataExpression.String("Owner"),
                                                                   MetadataExpression.String(owner)));

            return(true);
        }
예제 #12
0
        /// <summary>
        /// Analyzes the given assembly statically and gathers all declared entities
        /// such as member variables and local variables
        /// </summary>
        /// <param name="assembly"></param>
        public static void CollectAllDeclEntitiesInAssembly(AssemblyEx assembly)
        {
            SafeDebug.AssumeNotNull(assembly, "assembly");
            logger.Debug("Beginning of static analysis");
            if (ade == null)
            {
                ade = DUCoverStore.GetInstance();
            }

            foreach (TypeDefinition td in assembly.TypeDefinitions)
            {
                CollectAllDeclEntitiesInTypeDef(td);
            }
        }
예제 #13
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);
            }
예제 #14
0
        public MethodEffects(IFiniteSet <Field> writtenInstanceFields,
                             IFiniteSet <Field> directSetFields, IFiniteSet <Method> directCalledMethods, IFiniteSet <Field> returnFields,
                             SafeDictionary <Field, FieldModificationType> modificationTypeDic,
                             int callDepth)
        {
            SafeDebug.AssumeNotNull(writtenInstanceFields, "writtenInstanceFields");
            SafeDebug.Assume(callDepth >= 0, "callDepth>=0");

            this.WrittenInstanceFields      = writtenInstanceFields;
            this.DirectSetterFields         = directSetFields;
            this.DirectCalledMethods        = directCalledMethods;
            this.ReturnFields               = returnFields;
            this.ModificationTypeDictionary = modificationTypeDic;
            this.CallDepth = callDepth;
        }
예제 #15
0
        /// <inheritdoc/>
        public override void MarkIgnored(MethodDefinitionBuilder method, string message)
        {
            SafeDebug.AssumeNotNull(method, "method");

            var fact = method.CustomAttributes
                       .Cast <CustomAttributeBuilder>()
                       .FirstOrDefault(a => a.Constructor.SerializableName == XunitTestFrameworkMetadata.Ctor_FactAttribute);

            if (fact != null)
            {
                fact.AddNamedArgument(XunitTestFrameworkMetadata.Property_Skip, MetadataExpression.String(message));
                return;
            }

            SafeDebug.FailUnreachable();
        }
예제 #16
0
        public bool IsAssertMethod(MethodDefinition method, out int usefulParameters)
        {
            SafeDebug.AssumeNotNull(method, "method");

            TypeDefinition type;

            if (method.TryGetDeclaringType(out type) && type.SerializableName == XunitTestFrameworkMetadata.Type_Assert.Definition)
            {
                if (parameterCount.TryGetValue(method.ShortName, out usefulParameters))
                {
                    return(true);
                }
            }

            usefulParameters = -1;
            return(false);
        }
예제 #17
0
        internal SafeSet <Method> FilterCallingMethodsBasedOnField(Method tmw, Field field,
                                                                   SafeSet <Method> callingMethods)
        {
            SafeSet <Method> filteredMethods = new SafeSet <Method>();

            foreach (var callingm in callingMethods)
            {
                //Filter the calling method based on the field
                MethodBodyEx body;
                if (!callingm.TryGetBody(out body) || !body.HasInstructions)
                {
                    continue;
                }

                int         offset = 0;
                Instruction instruction;
                bool        bContinueWithNextMethod = false;
                Field       lastAccessedField       = null;
                while (body.TryGetInstruction(offset, out instruction) && !bContinueWithNextMethod)
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                        lastAccessedField = instruction.Field;
                    }
                    else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                    {
                        SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                        Method methodinner = instruction.Method;

                        if (methodinner == tmw && field == lastAccessedField)
                        {
                            filteredMethods.Add(callingm);
                            bContinueWithNextMethod = true;
                        }
                        lastAccessedField = null;
                    }
                    offset = instruction.NextOffset;
                }
            }
            return(filteredMethods);
        }
예제 #18
0
        /// <summary>
        /// Accepts a field and returns the persistent string form "assemblyname#typename#fieldname" of the field.
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        public static string GetPersistentStringFormOfField(Field f)
        {
            var            assemblyname = f.Definition.Module.Assembly.Location;
            string         typename;
            TypeDefinition typedef = null;

            if (!f.Definition.TryGetDeclaringType(out typedef))
            {
                SafeDebug.AssumeNotNull(typedef, "Type definition is empty");
                typename = PexMeConstants.PexMeDummyTypeName;
            }
            else
            {
                typename = typedef.FullName;
            }

            return(assemblyname + PexMeConstants.PexMePersistenceFormSeparator
                   + typename + PexMeConstants.PexMePersistenceFormSeparator + f.FullName);
        }
예제 #19
0
        /// <summary>
        /// Accepts a method and returns the persistent string form "assemblyname#typename#methodsignature" of the method.
        /// </summary>
        /// <param name="method"></param>
        /// <returns></returns>
        public static string GetPersistentStringFormOfMethod(Method m)
        {
            var            assemblyname = m.Definition.Module.Assembly.Location;
            string         typename;
            TypeDefinition typedef = null;

            if (!m.Definition.TryGetDeclaringType(out typedef))
            {
                SafeDebug.AssumeNotNull(typedef, "Type definition is empty");
                typename = PexMeConstants.PexMeDummyTypeName;
            }
            else
            {
                typename = typedef.FullName;
            }

            var signature = MethodOrFieldAnalyzer.GetMethodSignature(m);

            return(assemblyname + PexMeConstants.PexMePersistenceFormSeparator
                   + typename + PexMeConstants.PexMePersistenceFormSeparator + signature);
        }
예제 #20
0
        /// <inheritdoc/>
        public override bool IsTestIgnored(TestFrameworkTestSelection testSelection, MethodDefinition method, out string ignoreMessage)
        {
            SafeDebug.AssumeNotNull(testSelection, "testSelection");
            SafeDebug.AssumeNotNull(method, "method");

            var fact = method.DeclaredAttributes
                       .FirstOrDefault(a => a.Constructor.SerializableName == XunitTestFrameworkMetadata.Ctor_FactAttribute);

            if (fact != null)
            {
                var skip = fact.NamedArguments.FirstOrDefault(na => na.Name == "Skip");
                if (skip != null)
                {
                    ignoreMessage = ((MetadataExpression.StringExpression)skip.Value).Value;
                    return(true);
                }
            }

            ignoreMessage = null;
            return(false);
        }
예제 #21
0
        /// <summary>
        /// Populates all vertices
        /// </summary>
        /// <param name="method"></param>
        private void PopulateVertices(Method method)
        {
            MethodBodyEx body;

            if (!method.TryGetBody(out body) || !body.HasInstructions)
            {
                return;
            }

            int         offset = 0;
            Instruction instruction;

            while (body.TryGetInstruction(offset, out instruction))
            {
                SafeDebug.AssumeNotNull(instruction, "instruction");
                OpCode opCode = instruction.OpCode;

                InstructionVertex iv = this.AddVertex(instruction);
                this.vertices[offset] = iv;
                offset = instruction.NextOffset;
            }
        }
예제 #22
0
        /// <summary>
        /// Returns a method call for a PUT. This should be of certain characteristics,
        /// It should contain only one method call as generated by us
        /// </summary>
        /// <param name="putmethod"></param>
        /// <returns></returns>
        public static bool TryRetrieveMethodCall(Method putmethod, out Method assocmethod)
        {
            SafeDebug.AssumeNotNull(putmethod, "putmethod");
            assocmethod = null;

            MethodBodyEx mbodyex;
            bool         bresult = putmethod.TryGetBody(out mbodyex);

            SafeDebug.Assert(bresult, "Failed to get the body");

            int         offset = 0;
            Instruction instruction;

            List <Method> allCalledMethods = new List <Method>();

            while (mbodyex.TryGetInstruction(offset, out instruction))
            {
                SafeDebug.AssumeNotNull(instruction, "instruction");
                OpCode opCode = instruction.OpCode;

                if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                {
                    SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod,
                                     "opCode.OperandType == OperandType.InlineMethod");
                    allCalledMethods.Add(instruction.Method);
                }

                offset = instruction.NextOffset;
            }

            if (allCalledMethods.Count != 1)
            {
                return(false);
            }

            assocmethod = allCalledMethods[0];
            return(true);
        }
예제 #23
0
        public static TypeEx AddFieldToMethodEffects(IPexComponent host, TypeEx declaringType, SafeSet <string> res,
                                                     SafeSet <string> directSetFields, SafeDictionary <string, FieldModificationType> modificationTypeDic,
                                                     OpCode prevOpcode, Field field, TypeEx fieldType)
        {
            SafeDebug.AssumeNotNull(field, "field");
            SafeDebug.Assume(!field.IsStatic, "!field.IsStatic");

            TypeEx fieldDeclaringType;

            //The following check ensures that the field belongs to this class
            //or its base classes
            if (field.TryGetDeclaringType(out fieldDeclaringType) &&
                declaringType.IsAssignableTo(fieldDeclaringType))
            {
                res.Add(field.ShortName);

                FieldModificationType fmt = FieldModificationType.UNKNOWN;
                if (fieldType == SystemTypes.Int32 || fieldType == SystemTypes.Int64 || fieldType == SystemTypes.Int16)
                {
                    if (prevOpcode == OpCodes.Add)
                    {
                        fmt = FieldModificationType.INCREMENT;
                    }
                    else if (prevOpcode == OpCodes.Sub)
                    {
                        fmt = FieldModificationType.DECREMENT;
                    }
                    else if (prevOpcode == OpCodes.Call || prevOpcode == OpCodes.Calli || prevOpcode == OpCodes.Callvirt)
                    {
                        fmt = FieldModificationType.METHOD_CALL;
                    }
                    else
                    {
                        host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                            "Encountered unknown modification type for integer type " + prevOpcode);
                    }
                }
                else
                {
                    if (field.Type.IsReferenceType)
                    {
                        if (prevOpcode == OpCodes.Ldnull)
                        {
                            fmt = FieldModificationType.NULL_SET;
                        }
                        else if (prevOpcode == OpCodes.Newarr || prevOpcode == OpCodes.Newobj)
                        {
                            fmt = FieldModificationType.NON_NULL_SET;
                        }
                        else if (LdArgOpCodes.Contains(prevOpcode))
                        {
                            fmt = FieldModificationType.NON_NULL_SET;
                        }
                        else
                        {
                            fmt = FieldModificationType.METHOD_CALL;    //A method call is invoked on this field, which updates this field
                        }
                    }
                    else if (fieldType == SystemTypes.Bool)
                    {
                        if (prevOpcode == OpCodes.Ldc_I4_0)
                        {
                            fmt = FieldModificationType.FALSE_SET;
                        }
                        else if (prevOpcode == OpCodes.Ldc_I4_1)
                        {
                            fmt = FieldModificationType.TRUE_SET;
                        }
                        else
                        {
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for boolean type " + prevOpcode);
                        }
                    }
                }

                //Store the value of fmt. Sometimes, the same field
                //can be modified in different ways within the method, for example
                //setting a boolean field to both true or false. In that case, the modification
                //type is left as unknown
                FieldModificationType prevFMT;
                if (modificationTypeDic.TryGetValue(field.ShortName, out prevFMT))
                {
                    //There is some entry for this field
                    if (prevFMT != FieldModificationType.UNKNOWN && prevFMT != fmt)
                    {
                        modificationTypeDic[field.ShortName] = FieldModificationType.UNKNOWN;
                    }
                }
                else
                {
                    modificationTypeDic[field.ShortName] = fmt;
                }


                //A heuristic based approach for aliasing analysis for checking whether the field is directly
                //assigned any parameters
                if (LdArgOpCodes.Contains(prevOpcode))
                {
                    directSetFields.Add(field.ShortName);
                }
            }
            return(fieldDeclaringType);
        }
예제 #24
0
        /// <summary>
        /// Computes method effects statically. All written fields of a method.
        /// Can be imprecise and conservative
        /// </summary>
        /// <param name="declaringType"></param>
        /// <param name="method"></param>
        /// <param name="effects"></param>
        /// <returns></returns>
        public static bool TryComputeMethodEffects(IPexComponent host, TypeEx declaringType, Method method,
                                                   SafeSet <Method> visitedMethods, out MethodEffects effects)
        {
            SafeDebug.AssumeNotNull(declaringType, "declaringType");
            SafeDebug.AssumeNotNull(method, "method");

            try
            {
                if (visitedMethods == null)
                {
                    visitedMethods = new SafeSet <Method>();
                }

                if (visitedMethods.Contains(method))
                {
                    effects = null;
                    return(false);
                }

                visitedMethods.Add(method);

                //Check whether this has been computed before
                var psd = host.GetService <IPexMeStaticDatabase>() as PexMeStaticDatabase;
                if (psd.MethodEffectsDic.TryGetValue(method.GlobalIndex, out effects))
                {
                    return(true);
                }

                var res                 = new SafeSet <string>();
                var directSetFields     = new SafeSet <string>();
                var directCalledMethods = new SafeSet <Method>();
                var returnFields        = new SafeSet <Field>();
                var modificationTypeDic = new SafeDictionary <string, FieldModificationType>();
                var parameters          = method.Parameters;

                MethodBodyEx body;
                if (!method.TryGetBody(out body) || !body.HasInstructions)
                {
                    effects = null;
                    return(false);
                }

                int         callDepth = 0;
                int         offset    = 0;
                Instruction instruction;
                OpCode      prevOpcode = OpCodes.Nop;

                //Stack for load instructions
                Field lastAccessedArrayField = null;
                Field lastAccessedField      = null;

                while (body.TryGetInstruction(offset, out instruction))
                {
                    SafeDebug.AssumeNotNull(instruction, "instruction");
                    OpCode opCode = instruction.OpCode;
                    if (LdcOpCodes.Contains(opCode))
                    {
                        //topIsConstant = true;
                    }
                    else if (ConvOpCodes.Contains(opCode))
                    {
                        // do not change topIsConstant
                    }
                    else
                    {
                        if (opCode == OpCodes.Stfld)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field field = instruction.Field;
                            AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, field, field.Type);
                        }
                        else if (opCode == OpCodes.Ldfld || opCode == OpCodes.Ldflda)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineField, "opCode.OperandType == OperandType.InlineField");
                            Field accessedField = instruction.Field;

                            if (accessedField.Type.Spec == TypeSpec.SzArray)
                            {
                                lastAccessedArrayField = accessedField;
                            }
                            else
                            {
                                lastAccessedField = accessedField;
                            }
                        }
                        else if (StElemOpCodes.Contains(opCode))
                        {
                            if (lastAccessedArrayField != null)
                            {
                                //Indicates that there is n array type modified
                                AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic, prevOpcode, lastAccessedArrayField, lastAccessedArrayField.Type);
                                lastAccessedArrayField = null;
                            }
                        }
                        else if (opCode == OpCodes.Call || opCode == OpCodes.Callvirt)
                        {
                            SafeDebug.Assume(opCode.OperandType == OperandType.InlineMethod, "opCode.OperandType == OperandType.InlineMethod");
                            Method methodinner = instruction.Method;
                            SafeDebug.AssumeNotNull(method, "method");

                            directCalledMethods.Add(methodinner);
                            TypeEx methodDeclaringType;

                            //are these function calls are within the parent types
                            if (methodinner.TryGetDeclaringType(out methodDeclaringType) &&
                                declaringType.IsAssignableTo(methodDeclaringType))
                            {
                                MethodEffects methodEffects;
                                if (TryComputeMethodEffects(host, methodDeclaringType, methodinner, visitedMethods, out methodEffects))
                                {
                                    res.AddRange(methodEffects.WrittenInstanceFields);
                                    foreach (var key in methodEffects.ModificationTypeDictionary.Keys)
                                    {
                                        modificationTypeDic[key] = methodEffects.ModificationTypeDictionary[key];
                                    }
                                    directSetFields.AddRange(methodEffects.DirectSetterFields);
                                    if (methodEffects.CallDepth > callDepth)
                                    {
                                        callDepth = methodEffects.CallDepth;
                                    }
                                }
                            }
                            else
                            {
                                //introducing heuristics for inter-procedural static analysis
                                if (lastAccessedField != null && lastAccessedField.Type.IsReferenceType &&
                                    !(methodinner.ShortName.StartsWith("Get") || methodinner.ShortName.StartsWith("get") ||
                                      methodinner.ShortName.StartsWith("Set") || methodinner.ShortName.StartsWith("set")))
                                {
                                    AddFieldToMethodEffects(host, declaringType, res, directSetFields, modificationTypeDic,
                                                            prevOpcode, lastAccessedField, lastAccessedField.Type);
                                }
                            }
                        }
                        else if (opCode == OpCodes.Ret)
                        {
                            if (instruction.Field != null)
                            {
                                returnFields.Add(instruction.Field);
                            }
                        }
                        //topIsConstant = false;
                    }

                    prevOpcode = opCode;
                    offset     = instruction.NextOffset;
                }

                effects = new MethodEffects((IFiniteSet <string>)res, directSetFields, directCalledMethods, returnFields, modificationTypeDic, callDepth + 1);
                psd.MethodEffectsDic[method.GlobalIndex] = effects;
                return(true);
            }
            catch (Exception ex)
            {
                host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "methodeffects",
                                               "Failed to compute method effects for method " + method.FullName + "," + ex.Message);
                effects = null;
                return(false);
            }
        }
예제 #25
0
        /// <summary>
        /// Tries to get the assembly set up tear down attribute.
        /// </summary>
        /// <param name="assembly">The assembly.</param>
        /// <param name="setUp">The set up.</param>
        /// <param name="tearDown">The tear down.</param>
        /// <returns>True if found.</returns>
        public override bool TryGetAssemblySetupTeardownMethods(
            AssemblyEx assembly,
            out Method setUp,
            out Method tearDown)
        {
            // <preconditions>
            SafeDebug.AssumeNotNull((object)assembly, "assembly");

            // </preconditions>
            setUp = tearDown = null;

            // look for [TestClass] types
            foreach (var typeDefinition in assembly.TypeDefinitions)
            {
                if (typeDefinition.IsVisible(VisibilityContext.Exported))
                {
                    if (typeDefinition.IsEnumType ||
                        typeDefinition.GenericTypeParameters.Length > 0)
                    {
                        continue;
                    }

                    if (!this.IsFixture(typeDefinition))
                    {
                        continue;
                    }

                    // looking for assembly setup/teardown methods
                    foreach (var methodDefinition in typeDefinition.DeclaredStaticMethods)
                    {
                        if (methodDefinition.IsVisible(VisibilityContext.Exported) &&
                            methodDefinition.GenericMethodParameters.Length == 0)
                        {
                            if (AttributeHelper.IsDefined(methodDefinition, this.AssemblySetUpAttribute, true))
                            {
                                setUp = methodDefinition.Instantiate(TypeEx.NoTypes, TypeEx.NoTypes);
                            }

                            if (AttributeHelper.IsDefined(methodDefinition, this.AssemblyTearDownAttribute, true))
                            {
                                tearDown = methodDefinition.Instantiate(TypeEx.NoTypes, TypeEx.NoTypes);
                            }

                            // nothing else to look for
                            if (setUp != null && tearDown != null)
                            {
                                break;
                            }
                        }
                    }

                    // nothing else to look for
                    if (setUp != null && tearDown != null)
                    {
                        break;
                    }
                }
            }

            return(setUp != null || tearDown != null);
        }
예제 #26
0
        /// <summary>
        /// Initializes a new instance
        /// </summary>
        /// <param name="host">The host.</param>
        protected ComponentElementBase(IChessCopComponent host)
        {
            SafeDebug.AssumeNotNull(host, "host");

            this._host = host;
        }
예제 #27
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);
            }
        }
예제 #28
0
        /// <summary>
        /// Tries to load dynamic database
        /// </summary>
        /// <param name="pmd"></param>
        /// <returns></returns>
        public static bool TryLoadDynamicDatabase(PexMeDynamicDatabase pmd)
        {
            SafeDebug.AssumeNotNull(pmd, "pmd");

            var suggestionstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeFactorySuggestionStore);

            if (!File.Exists(suggestionstore))
            {
                pmd.FactorySuggestionsDictionary
                    = new System.Collections.Generic.Dictionary <string, PexMe.ObjectFactoryObserver.FactorySuggestionStore>();
            }
            else
            {
                try
                {
                    Stream          streamRead = File.OpenRead(suggestionstore);
                    BinaryFormatter binaryRead = new BinaryFormatter();
                    pmd.FactorySuggestionsDictionary = binaryRead.Deserialize(streamRead)
                                                       as System.Collections.Generic.Dictionary <string, FactorySuggestionStore>;
                    streamRead.Close();
                }
                catch (Exception ex)
                {
                    //host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpreader",
                    //    "Failed to read the factory suggestion store");
                    pmd.FactorySuggestionsDictionary
                        = new System.Collections.Generic.Dictionary <string, PexMe.ObjectFactoryObserver.FactorySuggestionStore>();
                }
            }

            if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE)
            {
                var fieldstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicFieldStore);
                if (!File.Exists(fieldstore))
                {
                    pmd.FieldDictionary = new SafeDictionary <Field, FieldStore>();
                }
                else
                {
                    try
                    {
                        Stream          streamRead = File.OpenRead(fieldstore);
                        BinaryFormatter binaryRead = new BinaryFormatter();
                        System.Collections.Generic.Dictionary <string, PersistentFieldStore> pfs = binaryRead.Deserialize(streamRead)
                                                                                                   as System.Collections.Generic.Dictionary <string, PersistentFieldStore>;
                        pmd.FieldDictionary = GetFieldDictionary(pmd, pfs);
                        streamRead.Close();
                    }
                    catch (Exception)
                    {
                        //host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpreader",
                        //    "Failed to read the dynamic field store");
                        pmd.FieldDictionary = new SafeDictionary <Field, FieldStore>();
                    }
                }
            }
            else
            {
                pmd.FieldDictionary = new SafeDictionary <Field, FieldStore>();
            }

            if (PexMeConstants.ENABLE_DYNAMICDB_STORAGE)
            {
                var methodstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicMethodStore);
                if (!File.Exists(methodstore))
                {
                    pmd.MethodDictionary = new SafeDictionary <Method, MethodStore>();
                }
                else
                {
                    try
                    {
                        Stream          streamRead = File.OpenRead(methodstore);
                        BinaryFormatter binaryRead = new BinaryFormatter();
                        System.Collections.Generic.Dictionary <string, PersistentMethodStore> pfs = binaryRead.Deserialize(streamRead)
                                                                                                    as System.Collections.Generic.Dictionary <string, PersistentMethodStore>;
                        pmd.MethodDictionary = GetMethodDictionary(pmd, pfs);
                        streamRead.Close();
                    }
                    catch (Exception)
                    {
                        //host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpreader",
                        //    "Failed to read the dynamic field store");
                        pmd.MethodDictionary = new SafeDictionary <Method, MethodStore>();
                    }
                }
            }
            else
            {
                pmd.MethodDictionary = new SafeDictionary <Method, MethodStore>();
            }

            var expstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMeDynamicExploredMethods);

            if (!File.Exists(expstore))
            {
                pmd.AllExploredMethods = new HashSet <string>();
            }
            else
            {
                try
                {
                    Stream          streamRead = File.OpenRead(expstore);
                    BinaryFormatter binaryRead = new BinaryFormatter();
                    pmd.AllExploredMethods = binaryRead.Deserialize(streamRead)
                                             as HashSet <string>;
                    streamRead.Close();
                }
                catch (Exception)
                {
                    //host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpreader",
                    //    "Failed to read the dynamic field store");
                    pmd.AllExploredMethods = new HashSet <string>();
                }
            }

            var pendingstore = Path.Combine(PexMeConstants.PexMeStorageDirectory, PexMeConstants.PexMePendingExplorationMethods);

            if (!File.Exists(pendingstore))
            {
                pmd.PendingExplorationMethods = new HashSet <string>();
            }
            else
            {
                try
                {
                    Stream          streamRead = File.OpenRead(pendingstore);
                    BinaryFormatter binaryRead = new BinaryFormatter();
                    pmd.PendingExplorationMethods = binaryRead.Deserialize(streamRead)
                                                    as HashSet <string>;
                    streamRead.Close();
                }
                catch (Exception)
                {
                    //host.Log.LogErrorFromException(ex, WikiTopics.MissingWikiTopic, "dumpreader",
                    //    "Failed to read the dynamic field store");
                    pmd.PendingExplorationMethods = new HashSet <string>();
                }
            }

            return(true);
        }
예제 #29
0
        /// <summary>
        /// Call-back that gets invoked when Pex requires a factory method
        /// for a specific type.
        /// TODO: May not be invoked when there is some existing factory method
        /// already there and the new uncovered branch is due to object creation issue
        /// Or will be invoked only if Pex thinks that it needs a factory method.
        /// </summary>
        /// <param name="explorableType"></param>
        /// <returns></returns>
        public IEnumerable <PexExplorableCandidate> GuessExplorables(TypeEx explorableType)
        {
            SafeDebug.AssumeNotNull(explorableType, "explorableType");

            this.host.Log.LogMessage(PexMeLogCategories.MethodBegin, "Beginning of PexMeFactoryGuesser.GuessExplorables method");
            this.host.Log.LogMessage(PexMeLogCategories.Debug, "Requested for type: " + explorableType);

            //A trick to make generics work properly with the combination of inheritance.
            //Check the class PreDefinedGenericClasses for more details of why this line of code is required
            PreDefinedGenericClasses.recentAccessedTypes.Add(explorableType.FullName);

            var visibilityContext = VisibilityContext.Exported;

            if (!explorableType.IsVisible(visibilityContext))//if the type is not public
            {
                yield break;
            }

            //Giving mseqgen factories the highest preferemce
            if (PexMeConstants.ENABLE_MSEQGEN_RECOMMENDER)
            {
                if (mseqgen == null)
                {
                    mseqgen = this.pmd.GetService <MSeqGenRecommender>();
                }

                foreach (var factory in mseqgen.GetMSeqGenFactories(explorableType))
                {
                    yield return(factory);
                }
            }

            //the following factory is not returned to be used in sequence explroation but used to check
            //whether things are valid
            PexExplorableFactory localExplorableFactory;
            bool result = PexExplorableFactory.TryGetExplorableFactory(this.host, explorableType, out localExplorableFactory);

            Method bestConstructorMethod = null;

            if (explorableType.DefaultConstructor == null)
            {
                #region scan visible constructors, order by call depth, select best constructor
                var  orderedMethodEffectsList = new SafeList <OrderedMethodEffects>();
                var  bestConstructor          = new OrderedMethodEffects();
                bool bNoVisibleConstructors   = true;
                foreach (var constructor in explorableType.GetVisibleInstanceConstructors(visibilityContext))
                {
                    if (!localExplorableFactory.IsValidFactoryMethod(constructor))
                    {
                        continue;
                    }
                    orderedMethodEffectsList.Add(new OrderedMethodEffects(this.host, constructor));
                    bNoVisibleConstructors = false;
                }

                if (!bNoVisibleConstructors)
                {
                    //Finding the default constructor. We always start with the default constructor
                    orderedMethodEffectsList.Sort();
                    foreach (var entry in orderedMethodEffectsList)
                    {
                        if (bestConstructor.Method == null ||
                            bestConstructor.Effects.WrittenInstanceFields.Count > entry.Effects.WrittenInstanceFields.Count)
                        {
                            bestConstructor = entry;
                        }
                    }

                    orderedMethodEffectsList.Clear();
                    if (bestConstructor.Method != null) //cannot find a constructor
                    {
                        bestConstructorMethod = bestConstructor.Method;
                    }
                }

                if (bestConstructorMethod == null)
                {
                    if (!TypeAnalyzer.TryGetProducingMethods(this.pmd, explorableType, out bestConstructorMethod))
                    {
                        yield break;
                    }
                }
                #endregion
            }
            else
            {
                bestConstructorMethod = explorableType.DefaultConstructor;
            }

            #region default factory method from the original Pex: scan visible methods, order by call depth, add methods as setters

            //start building the method sequence
            PexExplorableFactory originalExplorableFactory;
            result = PexExplorableFactory.TryGetExplorableFactory(this.Host, explorableType, out originalExplorableFactory);

            //add constructor
            if (!originalExplorableFactory.TrySetFactoryMethod(bestConstructorMethod))
            {
                SafeDebug.Fail("we checked before that it is valid");
                yield break;
            }

            IPexExplorable originalExplorable1 = originalExplorableFactory.CreateExplorable();
            CodeUpdate.AddMethodCodeUpdate originalPreviewUpdate1;
            CodeUpdate originalUpdate1 = originalExplorableFactory.CreateExplorableFactoryUpdate(out originalPreviewUpdate1);

            //return the original one after own suggested
            this.WriteOutMethodBody(explorableType, originalPreviewUpdate1);
            yield return(new PexExplorableCandidate(originalExplorable1, false, originalUpdate1));

            var fsuggestions = this.pmd.FactorySuggestionsDictionary;

            //No suggestions for this type are available
            FactorySuggestionStore fss;
            if (fsuggestions.Count != 0 && fsuggestions.TryGetValue(explorableType.ToString(), out fss))
            {
                var methodNameToMethodMapper     = new SafeDictionary <string, Method>();
                var propertyNameToPropertyMapper = new SafeDictionary <string, Property>();

                //Trying to add the remaining method setters
                ExtractMethodsAndProperties(explorableType, methodNameToMethodMapper, propertyNameToPropertyMapper);

                //PexMe suggested factory methods
                foreach (var msequence in fss.GetSuggestedMethodSequences(this.pmd))
                {
                    PexExplorableFactory pexmeExplorableFactory;
                    result = PexExplorableFactory.TryGetExplorableFactory(this.host, explorableType, out pexmeExplorableFactory);

                    bool bRecommendThisFactoryMethod = false;
                    try
                    {
                        //Check whether the sequence includes a constructor
                        //If yes use the constructor
                        Method bestConstructorMethodSuggested = null;
                        foreach (var methodid in msequence.Sequence)
                        {
                            if (!methodid.Contains("..ctor("))
                            {
                                continue;
                            }

                            Method tempMethod;
                            if (methodNameToMethodMapper.TryGetValue(methodid, out tempMethod))
                            {
                                bestConstructorMethodSuggested = tempMethod;
                            }
                            else
                            {
                                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                         "Failed to the get the method with ID: " + methodid);
                            }
                        }

                        if (bestConstructorMethodSuggested == null)
                        {
                            if (!pexmeExplorableFactory.TrySetFactoryMethod(bestConstructorMethod))
                            {
                                SafeDebug.Fail("we checked before that it is valid");
                                yield break;
                            }
                        }
                        else
                        {
                            if (!pexmeExplorableFactory.TrySetFactoryMethod(bestConstructorMethodSuggested))
                            {
                                this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                         "Failed to set best suggested constructor method " + bestConstructorMethodSuggested.FullName);
                                yield break;
                            }
                            else
                            {
                                bRecommendThisFactoryMethod = true;
                            }
                        }

                        //handle other methods
                        foreach (var methodid in msequence.Sequence)
                        {
                            if (methodid.Contains("..ctor("))
                            {
                                continue;
                            }

                            //Could be a setter method for the property
                            if (methodid.Contains("set_"))
                            {
                                Property prop;
                                if (propertyNameToPropertyMapper.TryGetValue(methodid, out prop))
                                {
                                    if (!pexmeExplorableFactory.TryAddPropertySetter(prop))
                                    {
                                        this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                                 "Failed to add property " + prop.FullName + " to the factory method");
                                    }
                                    else
                                    {
                                        bRecommendThisFactoryMethod = true;
                                    }

                                    continue;
                                }
                            }

                            Method smethod;
                            if (methodNameToMethodMapper.TryGetValue(methodid, out smethod))
                            {
                                if (!pexmeExplorableFactory.TryAddMethodSetter(smethod))
                                {
                                    this.host.Log.LogWarning(WikiTopics.MissingWikiTopic, "factoryguesser",
                                                             "Failed to add method " + smethod.FullName + " to the factory method");
                                }
                                else
                                {
                                    bRecommendThisFactoryMethod = true;
                                }
                            }
                        }
                    }
                    catch (System.Exception ex)
                    {
                        this.host.Log.LogError(WikiTopics.MissingWikiTopic, "ExplorableGuesser", " Exception occurred while constructing factory from suggested sequence " + ex.Message);
                        continue;
                    }

                    //no method are being added to this sequence. This can be of no use.
                    if (!bRecommendThisFactoryMethod)
                    {
                        continue;
                    }

                    IPexExplorable originalExplorable = pexmeExplorableFactory.CreateExplorable();
                    CodeUpdate.AddMethodCodeUpdate originalPreviewUpdate;
                    CodeUpdate originalUpdate = pexmeExplorableFactory.CreateExplorableFactoryUpdate(out originalPreviewUpdate);
                    this.WriteOutMethodBody(explorableType, originalPreviewUpdate);
                    yield return(new PexExplorableCandidate(originalExplorable, false, originalUpdate));
                }
            }



            #endregion
            yield break;
        }
예제 #30
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);
        }