/// <summary> /// Creates a new SARIF Result object with contents from the /// most recent result of the matched pair, the appropriate state, /// and some metadata in the property bag about the matching algorithm used. /// </summary> /// <returns>The new SARIF result.</returns> public Result CalculateBasedlinedResult(DictionaryMergeBehavior propertyBagMergeBehavior) { Result result = null; Dictionary <string, object> resultMatchingProperties = new Dictionary <string, object>(); Dictionary <string, object> originalResultMatchingProperties = null; if (PreviousResult != null && CurrentResult != null) { // Baseline result and current result have been matched => existing. result = ConstructExistingResult(resultMatchingProperties, out originalResultMatchingProperties); } else if (PreviousResult == null && CurrentResult != null) { // No baseline result, present current result => new. result = ConstructNewResult(resultMatchingProperties, out originalResultMatchingProperties); } else if (PreviousResult != null && CurrentResult == null) { // Baseline result is present, current result is missing => absent. result = ConstructAbsentResult(resultMatchingProperties, out originalResultMatchingProperties); } resultMatchingProperties = MergeDictionaryPreferFirst(resultMatchingProperties, originalResultMatchingProperties); if (PreviousResult != null && propertyBagMergeBehavior == DictionaryMergeBehavior.InitializeFromOldest) { result.Properties = PreviousResult.Result.Properties; } result.SetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, resultMatchingProperties); return(result); }
internal static void MergeDictionaryInto <T, S>( IDictionary <T, S> baseDictionary, IDictionary <T, S> dictionaryToAdd, IEqualityComparer <S> duplicateCatch, DictionaryMergeBehavior propertyBagMergeBehavior) { foreach (KeyValuePair <T, S> pair in dictionaryToAdd) { if (!baseDictionary.ContainsKey(pair.Key)) { // The baseline does not contain the current dictionary value. This means // that we can transport all properties associated with the new value. baseDictionary.Add(pair.Key, pair.Value); continue; } // We have a collision between a current and previously existing dictionary value. We need to strip // the properties, if any, from each value in order to perform a comparison of the core SARIF // data (which must be equivalent between the two instances. PropertyBagHolder basePropertyBagHolder, propertyBagHolderToMerge; IDictionary <string, SerializedPropertyInfo> baseProperties = null, propertiesToMerge = null; basePropertyBagHolder = baseDictionary[pair.Key] as PropertyBagHolder; if (basePropertyBagHolder != null) { propertyBagHolderToMerge = pair.Value as PropertyBagHolder; Debug.Assert(propertyBagHolderToMerge != null); baseProperties = basePropertyBagHolder.Properties; basePropertyBagHolder.Properties = null; propertiesToMerge = propertyBagHolderToMerge.Properties; propertyBagHolderToMerge.Properties = null; } ; // Now that we've emptied any properties, we can ensure that the base value and the value to // merge are equivalent. If they aren't we throw: there is no good way to understand which // construct to prefer. S baseValue = baseDictionary[pair.Key]; if (!duplicateCatch.Equals(baseValue, pair.Value)) { throw new InvalidOperationException( "We do not, at this moment, support merging dictionary " + "value that share a key but have different content."); } if (basePropertyBagHolder != null) { basePropertyBagHolder.Properties = propertyBagMergeBehavior == DictionaryMergeBehavior.InitializeFromMostRecent ? propertiesToMerge : baseProperties; } } }
public SarifLogResultMatcher( IEnumerable <IResultMatcher> exactResultMatchers, IEnumerable <IResultMatcher> heuristicMatchers, DictionaryMergeBehavior propertyBagMergeBehaviors = DictionaryMergeBehavior.None) { ExactResultMatchers = exactResultMatchers; HeuristicMatchers = heuristicMatchers; PropertyBagMergeBehavior = propertyBagMergeBehaviors; }
/// <summary> /// Creates a new SARIF Result object with contents from the /// most recent result of the matched pair, the appropriate state, /// and some metadata in the property bag about the matching algorithm used. /// </summary> /// <returns>The new SARIF result.</returns> public Result CalculateBasedlinedResult(DictionaryMergeBehavior propertyBagMergeBehavior) { Result result; Dictionary <string, object> ResultMatchingProperties = new Dictionary <string, object>(); Dictionary <string, object> OriginalResultMatchingProperties = null; if (PreviousResult != null && CurrentResult != null) { // Baseline result and current result have been matched => existing. result = ConstructExistingResult(ResultMatchingProperties, out OriginalResultMatchingProperties); } else if (PreviousResult == null && CurrentResult != null) { // No baseline result, present current result => new. result = ConstructNewResult(ResultMatchingProperties, out OriginalResultMatchingProperties); } else if (PreviousResult != null && CurrentResult == null) { // Baseline result is present, current result is missing => absent. result = ConstructAbsentResult(ResultMatchingProperties, out OriginalResultMatchingProperties); } else { throw new InvalidOperationException("Cannot generate a result for a new baseline where both results are null."); } ResultMatchingProperties = MergeDictionaryPreferFirst(ResultMatchingProperties, OriginalResultMatchingProperties); if (PreviousResult != null && propertyBagMergeBehavior == DictionaryMergeBehavior.InitializeFromOldest) { result.Properties = PreviousResult.Result.Properties; } result.SetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, ResultMatchingProperties); return(result); }