private static bool TryAddRegressionAttributeViaPex <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(Method method, string message, IOutput output, IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder, System.Type attributeType) { IFeedbackManager feedbackManager = GetFeedbackConnection(); bool success = false; if (feedbackManager != null) { ConstructorInfo attrCtor = attributeType.GetConstructor(new System.Type[1] { typeof(string) }); MethodDefinitionName target = Translate(method, output, mdDecoder); string group = Guid.NewGuid().ToString(); ICustomAttribute ca = new CustomAttributeBuilder(MetadataFromReflection.GetMethod(attrCtor), MetadataExpression.String(message)); CodeUpdate update = CodeUpdate.AddAttribute("Regression", target, ca); CodeFix fix = CodeFix.FromUpdate("ClousotRegression", "missing regression attribute", group, update, 100, CodeFixImage.Message); try { feedbackManager.AddFix(fix); success = true; } catch { } } return(success); }
private static bool TryAddRegressionAttributeViaPex <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(Method method, Enum outcome, string message, int primaryILOffset, int methodILOffset, IOutput output, IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder, System.Type attributeType) { IFeedbackManager feedbackManager = GetFeedbackConnection(); bool success = false; if (feedbackManager != null) { PropertyInfo outcomeProp = attributeType.GetProperty("Outcome"); PropertyInfo messageProp = attributeType.GetProperty("Message"); PropertyInfo primaryILProp = attributeType.GetProperty("PrimaryILOffset"); PropertyInfo methodILProp = attributeType.GetProperty("MethodILOffset"); ConstructorInfo attrCtor = attributeType.GetConstructor(new System.Type[0]); MethodDefinitionName target = Translate(method, output, mdDecoder); MethodName attributeCtorName = MetadataFromReflection.GetMethod(attrCtor).SerializableName; #if DEBUG_PEX_BY_XML SafeSimpleXmlWriter writer = SafeSimpleXmlWriter.Create(new StreamWriter(@"C:\temp\" + mdDecoder.Name(method) + ".xml"), true); target.WriteXml(writer, "method"); writer.Close(); SafeSimpleXmlWriter writer2 = SafeSimpleXmlWriter.Create(new StreamWriter(@"C:\temp\" + mdDecoder.Name(method) + "2.xml"), true); attributeCtorName2.WriteXml(writer2, "method"); writer2.Close(); #endif string group = Guid.NewGuid().ToString(); var outcomeArg = AttributeArgument.Named(MetadataFromReflection.GetProperty(outcomeProp), MetadataExpression.EnumValue(outcome)); #if DEBUG_PEX_BY_XML SafeSimpleXmlWriter writer3 = SafeSimpleXmlWriter.Create(new StreamWriter(@"C:\temp\" + mdDecoder.Name(method) + "3.xml"), true); outcomeArg.WriteXml(writer3, "method"); writer3.Close(); #endif CodeUpdate update = CodeUpdate.AddAttribute("Regression", target, attributeCtorName, outcomeArg, AttributeArgument.Named(MetadataFromReflection.GetProperty(messageProp), MetadataExpression.String(message)), AttributeArgument.Named(MetadataFromReflection.GetProperty(primaryILProp), MetadataExpression.I4(MetadataFromReflection.GetType(typeof(int)), primaryILOffset)), AttributeArgument.Named(MetadataFromReflection.GetProperty(methodILProp), MetadataExpression.I4(MetadataFromReflection.GetType(typeof(int)), methodILOffset)) ); CodeFix fix = CodeFix.FromUpdate("ClousotRegression", "missing regression attribute", group, update, 100, CodeFixImage.Message); try { feedbackManager.AddFix(fix); success = true; } catch { } } return(success); }
private static void SuggestPostConditionViaPex <Local, Parameter, Method, Field, Property, Event, Type, Expression, Variable, Attribute, Assembly>(IExpressionContext <Local, Parameter, Method, Field, Type, Expression, Variable> context, int rank, string symptom, IOutput output, IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder, string post) where Type : IEquatable <Type> { #if INCLUDE_PEXINTEGRATION IFeedbackManager feedbackManager = GetFeedbackConnection(); if (feedbackManager != null) { MethodDefinitionName target = Translate(context.MethodContext.CurrentMethod, output, mdDecoder); string group = Guid.NewGuid().ToString(); var microsoftContractsAssembly = ShortAssemblyName.FromName("Microsoft.Contracts"); CodeUpdate update = CodeUpdate.InsertCheck("Ensures", target, MakePostconditionString(post), new[] { "System.Diagnostics.Contracts" }, new[] { microsoftContractsAssembly }, "Clousot"); CodeFix fix = CodeFix.FromUpdate("Clousot", symptom, group, update, rank, CodeFixImage.Message); try { feedbackManager.AddFix(fix); } catch { } } #endif }
private static bool TryAddRegressionAttributeViaPex <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly>(Assembly assembly, string message, IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> mdDecoder, System.Type attributeType) { IFeedbackManager feedbackManager = GetFeedbackConnection(); bool success = true; if (feedbackManager != null) { ConstructorInfo attrCtor = attributeType.GetConstructor(new System.Type[1] { typeof(string) }); #if DEBUG_PEX_BY_XML SafeSimpleXmlWriter writer = SafeSimpleXmlWriter.Create(new StreamWriter(@"C:\temp\" + mdDecoder.Name(method) + ".xml"), true); target.WriteXml(writer, "method"); writer.Close(); SafeSimpleXmlWriter writer2 = SafeSimpleXmlWriter.Create(new StreamWriter(@"C:\temp\" + mdDecoder.Name(method) + "2.xml"), true); attributeCtorName2.WriteXml(writer2, "method"); writer2.Close(); #endif string group = Guid.NewGuid().ToString(); ICustomAttribute ca = new CustomAttributeBuilder(MetadataFromReflection.GetMethod(attrCtor), MetadataExpression.String(message)); CodeUpdate update = CodeUpdate.AddAttribute("Regression", new Microsoft.ExtendedReflection.Metadata.Names.ShortAssemblyName(mdDecoder.Name(assembly), null), ca); CodeFix fix = CodeFix.FromUpdate("ClousotRegression", "missing regression attribute", group, update, 100, CodeFixImage.Message); try { feedbackManager.AddFix(fix); success = true; } catch { } } return(success); }
/// <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; }
/// <summary> /// scans the assembly and identifies all MSeqGen generated factory methods /// </summary> /// <returns></returns> public void LoadExplorableCandidates() { var pmd = this.GetService <PexMeDynamicDatabase>(); var fss = pmd.FactorySuggestionsDictionary; foreach (var tdef in this.currAssembly.TypeDefinitions) { if (!tdef.ShortName.EndsWith(MSeqGenConstants.FACTORY_CLASS_SUFFIX)) { continue; } foreach (var mdef in tdef.DeclaredStaticMethods) { PexExplorableFactory originalExplorableFactory = null; TypeEx retTypeEx = null; try { var retType = mdef.ResultType; if (!MethodOrFieldAnalyzer.TryGetTypeExFromName(this, this.currAssembly, retType.ToString(), out retTypeEx)) { this.Log.LogWarning(WikiTopics.MissingWikiTopic, "MSeqGenRecommender", "Failed to set typeex for " + retType.ToString()); continue; } //var retTypeEx = MetadataFromReflection.GetType(retType.GetType()); var methodEx = mdef.Instantiate(MethodOrFieldAnalyzer.GetGenericTypeParameters(this, retTypeEx.Definition), MethodOrFieldAnalyzer.GetGenericMethodParameters(this, mdef)); var result = PexExplorableFactory.TryGetExplorableFactory(this, retTypeEx, out originalExplorableFactory); if (result == false) { this.Log.LogWarning(WikiTopics.MissingWikiTopic, "MSeqGenRecommender", "Failed to set create explorable for " + retTypeEx.FullName); continue; } //add constructor if (!originalExplorableFactory.TrySetFactoryMethod(methodEx)) { this.Log.LogWarning(WikiTopics.MissingWikiTopic, "MSeqGenRecommender", "Failed to set factory method for " + mdef.FullName); continue; } } catch (Exception ex) { this.Log.LogError(WikiTopics.MissingWikiTopic, "MSeqGenRecommender", "Error occurred while parsing MSeqGen factories " + ex.Message); } if (originalExplorableFactory == null) { continue; } IPexExplorable originalExplorable1 = originalExplorableFactory.CreateExplorable(); CodeUpdate.AddMethodCodeUpdate originalPreviewUpdate1; CodeUpdate originalUpdate1 = originalExplorableFactory.CreateExplorableFactoryUpdate(out originalPreviewUpdate1); this.AddToRecommendedFactories(retTypeEx.FullName, new PexExplorableCandidate(originalExplorable1, false, originalUpdate1)); } } }