/// <summary>
 /// Gets called when an un-explored branch is encountered during program execution
 /// </summary>
 /// <param name="executionNode"></param>
 /// <param name="explorableType"></param>
 public void LogExplorableInsufficiency(IExecutionNode executionNode, TypeEx explorableType)
 {
     var termManager = this.ExplorationServices.TermManager;
     var condition = executionNode.SuccessorLabelToExplore;
     this.GatherDebuggingInfoFromInsufficiency(executionNode, termManager, condition, explorableType);
     this.tba.HandleTargetBranch(executionNode.CodeLocation, condition, termManager, explorableType);
 }
Beispiel #2
0
        /// <summary>
        /// Includes what are the types supported
        /// </summary>
        /// <returns></returns>
        public static bool IsPrimitiveType(TypeEx type)
        {
            if (type.IsPrimitiveImmutable || PrimitiveTypes.Contains(type) || type.IsStringType)
                return true;

            return false;
        }
Beispiel #3
0
        /// <summary>
        /// Includes what are the types supported
        /// </summary>
        /// <returns></returns>
        public static bool IsTypeSupported(TypeEx type)
        {
            if (type.Spec == TypeSpec.SzArray || type.IsPrimitiveImmutable || PrimitiveTypes.Contains(type) ||
                type.IsStringType || type.Spec == TypeSpec.Class)
                return true;

            return false;
        }
        /// <summary>
        /// Returns the loaded factory methods
        /// </summary>
        /// <param name="typeEx"></param>
        /// <returns></returns>
        public IEnumerable<PexExplorableCandidate> GetMSeqGenFactories(TypeEx typeEx)
        {
            SafeList<PexExplorableCandidate> existingList;
            if (!this.recommendedFactories.TryGetValue(typeEx.FullName, out existingList))
                yield break;

            foreach (var factory in existingList)
                yield return factory;
        }
        public bool TryGetTypeHints(TypeEx type, 
            out IIndexable<TypeDefinition> hints)
        {
            hints = null;
            if (!PexMeConstants.ENABLE_TYPE_HINT_PROVIDER)
                return false;

            hints = null;
            this.pmd.Log.LogMessage("Hint provider", "Requested for types of interface or class: " + type.FullName.ToString());

            if (TypeAnalyzer.TryGetExtendingClasses(this.psd, type, out hints))
                return true;

            return false;
        }
        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;
        }
        public static bool HasFlag(this Enum value, Enum flag)
        {
            if (value == null)
            {
                throw new NullReferenceException();
            }

            if (flag == null)
            {
                throw new ArgumentNullException(nameof(flag));
            }

            var type = value.GetType();

            if (flag.GetType() != type)
            {
                throw new ArgumentException("Enum types don't match");
            }

            var typeCode = TypeEx.GetTypeCode(type);

            if (typeCode == TypeCode.Byte)
            {
                var byteFlag = Convert.ToByte(flag, CultureInfo.InvariantCulture);
                return((Convert.ToByte(value, CultureInfo.InvariantCulture) & byteFlag) == byteFlag);
            }

            if (typeCode == TypeCode.Int16)
            {
                var int16Flag = Convert.ToInt16(flag, CultureInfo.InvariantCulture);
                return((Convert.ToInt16(value, CultureInfo.InvariantCulture) & int16Flag) == int16Flag);
            }

            if (typeCode == TypeCode.Int32)
            {
                var int32Flag = Convert.ToInt32(flag, CultureInfo.InvariantCulture);
                return((Convert.ToInt32(value, CultureInfo.InvariantCulture) & int32Flag) == int32Flag);
            }

            if (typeCode == TypeCode.Int64)
            {
                var int64Flag = Convert.ToInt64(flag, CultureInfo.InvariantCulture);
                return((Convert.ToInt64(value, CultureInfo.InvariantCulture) & int64Flag) == int64Flag);
            }

            if (typeCode == TypeCode.SByte)
            {
                var sbyteFlag = Convert.ToSByte(flag, CultureInfo.InvariantCulture);
                return((Convert.ToSByte(value, CultureInfo.InvariantCulture) & sbyteFlag) == sbyteFlag);
            }

            if (typeCode == TypeCode.UInt16)
            {
                var uint16Flag = Convert.ToUInt16(flag, CultureInfo.InvariantCulture);
                return((Convert.ToUInt16(value, CultureInfo.InvariantCulture) & uint16Flag) == uint16Flag);
            }

            if (typeCode == TypeCode.UInt32)
            {
                var uint32Flag = Convert.ToUInt32(flag, CultureInfo.InvariantCulture);
                return((Convert.ToUInt32(value, CultureInfo.InvariantCulture) & uint32Flag) == uint32Flag);
            }

            if (typeCode == TypeCode.UInt64)
            {
                var uint64Flag = Convert.ToUInt64(flag, CultureInfo.InvariantCulture);
                return((Convert.ToUInt64(value, CultureInfo.InvariantCulture) & uint64Flag) == uint64Flag);
            }

            throw new InvalidOperationException("The underlying type of the Enum is not a recognized primitive integer type.");
        }
        private static TypeEx AddFieldToMethodEffects(IPexComponent host, TypeEx declaringType, SafeSet<Field> res,
            SafeSet<Field> directSetFields,
            SafeDictionary<Field, 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);

                var fieldTypeStr = fieldType.ToString();
                if (fieldTypeStr == "System.Int32" || fieldTypeStr == "System.Int64" || fieldTypeStr == "System.Int16")
                {
                    if (prevOpcode == OpCodes.Add)
                        modificationTypeDic[field] = FieldModificationType.INCREMENT;
                    else if (prevOpcode == OpCodes.Sub)
                        modificationTypeDic[field] = FieldModificationType.DECREMENT;
                    else
                        host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                            "Encountered unknown modification type for integer type " + prevOpcode);
                }
                else
                {
                    if (field.Type.IsReferenceType)
                    {
                        if (prevOpcode == OpCodes.Ldnull)
                            modificationTypeDic[field] = FieldModificationType.NULL_SET;
                        else if (prevOpcode == OpCodes.Newarr || prevOpcode == OpCodes.Newobj)
                            modificationTypeDic[field] = FieldModificationType.NON_NULL_SET;
                        else
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for reference type " + prevOpcode);
                    }
                    else if (fieldTypeStr == "System.Boolean")
                    {
                        if (prevOpcode == OpCodes.Ldc_I4_0)
                            modificationTypeDic[field] = FieldModificationType.FALSE_SET;
                        else if (prevOpcode == OpCodes.Ldc_I4_1)
                            modificationTypeDic[field] = FieldModificationType.TRUE_SET;
                        else
                            host.Log.LogWarning(WikiTopics.MissingWikiTopic, "fieldmodificationtype",
                                                "Encountered unknown modification type for boolean type " + prevOpcode);
                    }
                }

                //A heuristic based approach for aliasing analysis for checking whether the field is directly
                //assigned any parameters
                if (LdArgOpCodes.Contains(prevOpcode))
                    directSetFields.Add(field);
            }
            return fieldDeclaringType;
        }
        /// <summary>
        /// Accepts a type in the form "assemblyname#typename" and returns the type name
        /// </summary>
        /// <param name="Field"></param>
        /// <returns></returns>
        public static bool TryGetTypeExFromPersistentStringForm(IPexComponent host, string typename, out TypeEx typeEx)
        {
            typeEx = null;

            var splitarr = typename.Split(new char[] { PexMeConstants.PexMePersistenceFormSeparator });
            SafeDebug.Assume(splitarr.Length == 2, "Incorrect persistent store type name");

            try
            {
                bool result = TryGetTypeExFromName(host, splitarr[0], splitarr[1], out typeEx);
                if (typeEx == null || !result)
                    return false;

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
            public override PexResultTracking GetResultTreatment(PexTrackingThread thread, int callId,
                IMethodSignature methodSignature, TypeEx[] varArgTypes,
                bool hasDerivedResult)
            {
                // track uninstrumented method calls
                if (!hasDerivedResult)
                {
                    var method = methodSignature as Method;
                    if (method.FullName.Equals(_trackMethod.FullName))
                    {
                        if (track)
                        {
                            Dump("start to track " + method.FullName);
                            TrackingMethods.Add(method);
                            return PexResultTracking.Track;
                        }
                        Dump("method " + method.FullName + " is not tracked!");
                    }

                //                    IssueTrackDatabase db;
                //                    if (host.TryGetService<IssueTrackDatabase>(out db))
                //                    {
                ////                        host.Log.Dump("size", "size", "uninstrumented methods: " + db.UnInstrumentedMethods.Count);
                //                        foreach (var uninstrumentedMethod in db.UnInstrumentedMethods)
                //                        {
                ////                            host.Log.Dump("Method", "Method", "uninstrumented methods: " + uninstrumentedMethod.Method.FullName);
                ////                            host.Log.Dump("Method", "Method2", "methods: " + method.Definition.FullName);
                //                            if (uninstrumentedMethod.Method.FullName.Equals(method.FullName))
                //                            {
                ////                                host.Log.Dump("Method", "track", "track: " + method.Definition.FullName);
                //                                if (TrackingMethods.Add(method))
                //                                {
                //                                    return PexResultTracking.Track;
                //                                }
                //                            }
                //                        }
                //                    }
                }

                return PexResultTracking.ConcreteOrDerived;
            }
        /// <summary>
        /// Tries to get a property that modifies the given field
        /// </summary>
        /// <param name="host"></param>
        /// <param name="type"></param>
        /// <param name="field"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static bool TryGetPropertyModifyingField(IPexComponent host, TypeEx type, Field field, out Property property)
        {
            foreach (Property prop in type.DeclaredProperties)
            {
                Method setter = prop.Setter;
                if (setter == null)
                    continue;

                MethodEffects me;
                if (TryComputeMethodEffects(host, type, setter, null, out me) && me.WrittenInstanceFields.Contains(field.ShortName))
                {
                    FieldModificationType fmt;
                    if (me.ModificationTypeDictionary.TryGetValue(field.ShortName, out fmt) && fmt != FieldModificationType.METHOD_CALL
                        && fmt != FieldModificationType.UNKNOWN)
                    {
                        property = prop;
                        return true;
                    }
                }
            }

            var baseType = type.BaseType;
            if (baseType != null)
            {
                if (TryGetPropertyModifyingField(host, baseType, field, out property))
                    return true;
            }

            property = null;
            return false;
        }
 public static bool TryGetTypeExFromName(IPexComponent host, string assemblyname, string typename, out TypeEx typeEx)
 {
     typeEx = null;
     AssemblyEx assembly;
     ReflectionHelper.TryLoadAssemblyEx(assemblyname, out assembly);
     return TryGetTypeExFromName(host, assembly, typename, out typeEx);
 }
        /// <summary>
        /// Gets the type definition of a field
        /// </summary>
        /// <param name="host"></param>
        /// <param name="field"></param>
        /// <param name="ftex"></param>
        /// <returns></returns>
        public static bool TryGetDeclaringTypeEx(IPexComponent host, Field field, out TypeEx ftex)
        {
            var fdefinition = field.Definition;
            TypeDefinition td;
            if (!fdefinition.TryGetDeclaringType(out td))
            {
                host.Log.LogError(WikiTopics.MissingWikiTopic, "fieldanalyzer",
                    "Failed to retrieve the declaring type of the field " + field.FullName);
                ftex = null;
                return false;
            }

            ftex = td.Instantiate(GetGenericTypeParameters(host, td));
            return true;
        }
        /// <summary>
        /// Returns true if the field is visible externally of the given type
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public static bool IsFieldExternallyVisible(IPexComponent host, TypeEx type, Field field)
        {
            var visibilityContext = VisibilityContext.Exported;

            //Step 1: Is field visible externally?
            if (field.IsVisible(visibilityContext))
                return true;

            //Step 2: Check whether this is an associated property and see whether it is public
            Property property;
            if (TryGetPropertyModifyingField(host, type, field, out property))
            {
                if (property.IsVisible(visibilityContext))
                    return true;
            }

            //Step 3: Check whether any constructor directly sets this field
            foreach (Method constructor in type.GetVisibleInstanceConstructors(visibilityContext))
            {
                MethodEffects me;
                if (TryComputeMethodEffects(host, type, constructor, null, out me))
                {
                    if (me.DirectSetterFields.Contains(field.ShortName))
                        return true;
                }
            }

            return false;
        }
        /// <summary>
        /// Given a type definition, this function gets the generic parameters
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static TypeEx[] GetGenericTypeParameters(IPexComponent host, TypeDefinition tdef)
        {
            TypeEx[] typErr = new TypeEx[tdef.GenericTypeParametersCount];
            TypeEx inttype = MetadataFromReflection.GetType(typeof(int));
            int count = 0;
            foreach (var genp in tdef.GenericTypeParameters)
            {
                TypeEx predefTypeEx;
                if (PreDefinedGenericClasses.TryGetInstantiatedClass(host, genp.Name, tdef, out predefTypeEx))
                    typErr[count] = predefTypeEx;
                else
                    typErr[count] = inttype;
                count++;
            }

            return typErr;
        }
        // Find out how many fields require user provided factory methods
        public static bool GetTargetExplorableField(IEnumerable<Field> involvedFields, out Field targetField,
            out TypeEx declaringType, IPexComponent host,out TypeEx targetType)
        {
            targetField = null;
            var allInvolvedFields = new SafeList<Field>();
            allInvolvedFields.AddRange(involvedFields);
            int numFields = allInvolvedFields.Count;
            if (numFields < 1)
            {
                declaringType = null;
                targetType = null;
                return false;
            }
            //
            //            if (numFields == 1)
            //            {
            //                targetField = allInvolvedFields[0];
            //                if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeDefinition(host, targetField, out declaringType))
            //                {
            //                    declaringType = null;
            //                    return false;
            //                }
            //                return true;
            //            }

            //            allInvolvedFields.Reverse();
            TypeEx prevFieldType = null;
            for (int count = 0; count < allInvolvedFields.Count; count++)
            {
                var currentField = allInvolvedFields[count];
            //                if (count + 1 < allInvolvedFields.Count)
            //                {
            //                    prevFieldType = allInvolvedFields[count + 1].Type;
            //                }

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

                try
                {
                    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;
                    }
                }
                catch (Exception ex)
                {
                    ErrorLog.AppendLine("Failed to compute external visibility of field " + currentField.FullName + " because of " + ex);
                }

                targetField = currentField;
                targetType = declaringType;
                return true;
            }

            targetField = allInvolvedFields[allInvolvedFields.Count - 1];
            if (!MethodOrFieldAnalyzer.TryGetDeclaringTypeDefinition(host, targetField, out declaringType))
            {
                host.Log.LogError(WikiTopics.MissingWikiTopic, "targetfield",
                                  "Failed to get the declaring type for the field " + targetField.FullName);
                targetType = null;
                return false;
            }
            targetType = targetField.Type;
            return true;
        }
        private void processArrayResult(PexTrackingFrame frame, Field f, TypeEx type, Term initialElementValue, Term fieldValue, Term initialValue)
        {
            //below handles array-type fields
            if (type.Spec == TypeSpec.SzArray &&//is array
                !this.TermManager.IsDefaultValue(fieldValue))//is not null pointer
            {
                Term index = this.TermManager.Symbol(SzArrayIndexId.Instance);

                Term elementValue = frame.Thread.State.ReadSzArrayElement(type.ElementType.Layout, fieldValue, index);

                if (elementValue != initialElementValue)
                    this.explorationObserver.HandleMonitoredField(
                        frame.Method,
                        f,
                        new Term[] { index },
                        this.TermManager.Widen(elementValue, type.ElementType.StackWidening),
                        initialValue); //some complicated trick, no need to know
            }
        }
 /// <summary>
 /// Accepts a type and returns the persistent string form "assemblyname#typename" of the type.
 /// </summary>
 /// <param name="method"></param>
 /// <returns></returns>
 public static string GetPersistentStringFormOfTypeEx(TypeEx type)
 {
     var assemblyname = type.Definition.Module.Assembly.Location;
     return assemblyname + PexMeConstants.PexMePersistenceFormSeparator + type.FullName;
 }
 /// <inheritdoc/>
 public override bool IsFixtureIgnored(TestFrameworkTestSelection testSelection, TypeEx fixtureType, out string ignoreMessage)
 {
     // xUnit.net does not support skipping test classes
     ignoreMessage = null;
     return false;
 }
        /// <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;
            }
        }
 /// <inheritdoc/>
 public override bool TryGetFixtureSetupTeardownMethods(TypeEx type, out Method fixtureSetup, out Method fixtureTeardown, out Method testSetup, out Method testTeardown)
 {
     // Constructor and Dispose are supported natively
     testSetup = testTeardown = fixtureSetup = fixtureTeardown = null;
     return false;
 }
        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;
        }
 /// <inheritdoc/>
 public override bool TryReadExpectedException(ICustomAttributeProviderEx target, out TypeEx exceptionType)
 {
     // xUnit.net does not have an [ExpectedException] attribute
     exceptionType = null;
     return false;
 }
        /// <summary>
        /// Tries to get a property that returns a given field. Needs to go base classes
        /// also
        /// </summary>
        /// <param name="host"></param>
        /// <param name="type"></param>
        /// <param name="field"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static bool TryGetPropertyReadingField(IPexComponent host, TypeEx type, Field field, out Property property)
        {
            if (type == null)
            {
                property = null;
                return false;
            }

            if (type.DeclaredProperties != null)
            {
                foreach (Property prop in type.DeclaredProperties)
                {
                    Method getter = prop.Getter;
                    if (getter == null)
                        continue;

                    MethodEffects me;
                    if (TryComputeMethodEffects(host, type, getter, null, out me) && me.ReturnFields.Contains(field))
                    {
                        property = prop;
                        return true;
                    }
                }
            }

            var baseType = type.BaseType;
            if (baseType != null)
            {
                if (TryGetPropertyReadingField(host, baseType, field, out property))
                    return true;
            }

            property = null;
            return false;
        }
 public DeclClassEntity(TypeEx td)
 {
     this.td = td;
     this.host = DUCoverStore.GetInstance().Host;
 }
        public static bool TryGetTypeExFromName(IPexComponent host, AssemblyEx assembly, string typename, out TypeEx typeEx)
        {
            if(typeExCache.TryGetValue(typename, out typeEx))
                return true;

            typeEx = null;
            foreach (var assemtype in assembly.TypeDefinitions)
            {
                if (assemtype.FullName == typename)
                {
                    typeEx = assemtype.Instantiate(GetGenericTypeParameters(host, assemtype));
                    typeExCache.Add(typename, typeEx);
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// Tries the read expected exception.
        /// </summary>
        /// <param name="target">
        /// The method.
        /// </param>
        /// <param name="exceptionType">
        /// Type of the exception.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public override bool TryReadExpectedException(ICustomAttributeProviderEx target, out TypeEx exceptionType)
        {
            var attribute = AttributeHelper.GetAttribute(target, ExpectedExceptionAttribute);
            if (attribute != null)
            {
                var attributeType = attribute.GetType();

                // read exception type using reflection.
                var field = attributeType.GetField("expectedException", BindingFlags.NonPublic | BindingFlags.Instance);
                if (field != null)
                {
                    var t = field.GetValue(attribute) as Type;
                    bool isClass;
                    if (t != null && ReflectionHelper.TryGetIsClass(t, out isClass) && isClass
                        && !ReflectionHelper.ContainsGenericParameters(t))
                    {
                        exceptionType = MetadataFromReflection.GetType(t);
                        return true;
                    }
                }
            }

            exceptionType = null;
            return false;
        }
            public override int GetNextCallId(int threadId, int offset, IMethodSignature methodSignature, TypeEx[] varArgTypes, Term[] arguments)
            {
                DumpInfo(methodSignature, threadId, offset, varArgTypes);
                var termManager = host.ExplorationServices.TermManager;
                var method = methodSignature as Method;
                if (method != null)
                {
                    Dump("method name: " + method.FullName + " offset: " + offset);
                    if (!method.FullName.Equals(_trackMethod.FullName))
                    {
                        Dump("method: " + method.FullName + " is not tracking method " + _trackMethod);
                        Dump("end GetNextCallId=============================");
                        Dump("");
                        return 0;
                    }
                }

                if (method != null)
                {
                    Dump("method name: " + method.FullName);
                    if (method.FullName.Equals(_trackMethod.FullName))
                    {
                        bool foundSymbol = false;
                        if (arguments == null)
                        {
                            Dump("args is null");
                        }
                        else
                        {
                            string arg = "";
                            foreach (Term term in arguments)
                            {
                                arg += "arg: " + term + " is symbolic: " + termManager.IsSymbol(term);
                                var extractor = new ResultTrackConditionExtractor(termManager);
                                extractor.VisitTerm(default(TVoid), term);
                                arg += " symbol: " + extractor.Log;
                            }
                            Dump("args: " + arg);

                            foreach (Term argument in arguments)
                            {
                                if (termManager.IsSymbol(argument))
                                {
                                    foundSymbol = true;
                                    break;
                                }
                            }
                        }

                        track = foundSymbol;
                        if (track)
                        {
                            Dump("track " + method.FullName);
                            trackArg = true;
                            methodForTrackingArg = method;
                            Dump("track parameter of " + method.FullName);
                        }
                    }
                }
                else
                {
                    Dump(methodSignature + " signature is null.");
                }

                Dump("end GetNextCallId=============================");
                Dump("");
                return 0;
            }
        /// <summary>
        /// Gets the type definition of a field
        /// </summary>
        /// <param name="host"></param>
        /// <param name="field"></param>
        /// <param name="ftex"></param>
        /// <returns></returns>
        public static bool TryGetDeclaringTypeDefinition(IPexComponent host, Field field, out TypeEx ftex)
        {
            var fdefinition = field.Definition;
            TypeDefinition td;
            if (!fdefinition.TryGetDeclaringType(out td))
            {
                host.Log.LogError(WikiTopics.MissingWikiTopic, "fieldanalyzer",
                                  "Failed to retrieve the declaring type of the field " + field.FullName);
                ftex = null;
                return false;
            }
            try
            {
                ftex = td.Instantiate(new TypeEx[0]);
            }
            catch (ArgumentException argEx)
            {
                ftex = td.Instantiate(new TypeEx[] {MetadataFromReflection.GetType(typeof(object))});
            }
            catch (Exception ex)
            {
                ftex = null;
                Log.AppendLine("Instantiate typeEx fail: " + ex);
            }

            return true;
        }
            private void DumpInfo(IMethodSignature methodSignature, int threadId, int offset, TypeEx[] varArgTypes)
            {
                Dump("in GetNextCallId=============================");
                Dump("method of the stack: " + methodStack.Peek().FullName);
                try
                {
                    Dump("threadId: " + threadId + " offset: " + offset + " method: " + methodSignature);
                    if (varArgTypes == null)
                    {
                        Dump("types is null");
                    }
                    else
                    {

                        string types = "";
                        foreach (TypeEx ex in varArgTypes)
                        {
                            types += "varArgType: " + ex + ", ";
                        }
                        Dump("types: " + types);
                    }

                }
                catch (Exception e)
                {
                    Dump(e.Message + " trace: " +e.StackTrace);
                }
            }
        /// <summary>
        /// Tries to get a property that modifies the given field
        /// </summary>
        /// <param name="host"></param>
        /// <param name="type"></param>
        /// <param name="field"></param>
        /// <param name="property"></param>
        /// <returns></returns>
        public static bool TryGetPropertyModifyingField(IPexComponent host, TypeEx type, Field field,
            out Property property)
        {
            foreach (Property prop in type.DeclaredProperties)
            {
                Method setter = prop.Setter;
                if (setter == null)
                    continue;

                MethodEffects me;
                if (TryComputeMethodEffects(host, type, setter, null, out me) &&
                    me.WrittenInstanceFields.Contains(field))
                {
                    property = prop;
                    return true;
                }
            }

            var baseType = type.BaseType;
            if (baseType != null)
            {
                TryGetPropertyModifyingField(host, baseType, field, out property);
            }

            property = null;
            return false;
        }