<commit_before>// Copyright (c) 2007, <NAME>, Manas Technology Solutions, InSTEDD.
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Moq
{
	internal sealed class SetupCollection
	{
		private List<Setup> setups;

		public SetupCollection()
		{
			this.setups = new List<Setup>();
		}

		public void Add(Setup setup)
		{
			lock (this.setups)
			{
				this.setups.Add(setup);
			}
		}

		public bool Any(Func<Setup, bool> predicate)
		{
			lock (this.setups)
			{
				return this.setups.Any(predicate);
			}
		}

		public void Clear()
		{
			lock (this.setups)
			{
				this.setups.Clear();
			}
		}

		public Setup FindMatchFor(Invocation invocation)
		{
			// Fast path (no `lock`) when there are no setups:
			if (this.setups.Count == 0)
			{
				return null;
			}

			Setup matchingSetup = null;

			lock (this.setups)
			{
				// Iterating in reverse order because newer setups are more relevant than (i.e. override) older ones
				for (int i = this.setups.Count - 1; i >= 0; --i)
				{
					var setup = this.setups[i];

					// the following conditions are repetitive, but were written that way to avoid
					// unnecessary expensive calls to `setup.Matches`; cheap tests are run first.
					if (matchingSetup == null && setup.Matches(invocation))
					{
						matchingSetup = setup;
						if (setup.Method == invocation.Method)
						{
							break;
						}
					}
					else if (setup.Method == invocation.Method && setup.Matches(invocation))
					{
						matchingSetup = setup;
						break;
					}
				}
			}

			return matchingSetup;
		}

		public IEnumerable<Setup> GetInnerMockSetups()
		{
			return this.ToArrayLive(setup => setup.ReturnsInnerMock(out _));
		}

		public Setup[] ToArrayLive(Func<Setup, bool> predicate)
		{
			var matchingSetups = new Stack<Setup>();
			var visitedSetups = new HashSet<InvocationShape>();

			lock (this.setups)
			{
				// Iterating in reverse order because newer setups are more relevant than (i.e. override) older ones
				for (int i = this.setups.Count - 1; i >= 0; --i)
				{
					var setup = this.setups[i];

					if (setup.Condition != null)
					{
						continue;
					}

					if (!visitedSetups.Add(setup.Expectation))
					{
						// A setup with the same expression has already been iterated over,
						// meaning that this older setup is an overridden one.
						continue;
					}

					if (predicate(setup))
					{
						matchingSetups.Push(setup);<commit_msg>Flag setups that are known to be overridden<commit_after>// Copyright (c) 2007, <NAME>, Manas Technology Solutions, InSTEDD.
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Moq
{
	internal sealed class SetupCollection
	{
		private List<Setup> setups;
		private uint overridden;  // bit mask for the first 32 setups flagging those known to be overridden

		public SetupCollection()
		{
			this.setups = new List<Setup>();
			this.overridden = 0U;
		}

		public void Add(Setup setup)
		{
			lock (this.setups)
			{
				this.setups.Add(setup);
			}
		}

		public bool Any(Func<Setup, bool> predicate)
		{
			lock (this.setups)
			{
				return this.setups.Any(predicate);
			}
		}

		public void Clear()
		{
			lock (this.setups)
			{
				this.setups.Clear();
				this.overridden = 0U;
			}
		}

		public Setup FindMatchFor(Invocation invocation)
		{
			// Fast path (no `lock`) when there are no setups:
			if (this.setups.Count == 0)
			{
				return null;
			}

			Setup matchingSetup = null;

			lock (this.setups)
			{
				// Iterating in reverse order because newer setups are more relevant than (i.e. override) older ones
				for (int i = this.setups.Count - 1; i >= 0; --i)
				{
					if (i < 32 && (this.overridden & (1U << i)) != 0) continue;

					var setup = this.setups[i];

					// the following conditions are repetitive, but were written that way to avoid
					// unnecessary expensive calls to `setup.Matches`; cheap tests are run first.
					if (matchingSetup == null && setup.Matches(invocation))
					{
						matchingSetup = setup;
						if (setup.Method == invocation.Method)
						{
							break;
						}
					}
					else if (setup.Method == invocation.Method && setup.Matches(invocation))
					{
						matchingSetup = setup;
						break;
					}
				}
			}

			return matchingSetup;
		}

		public IEnumerable<Setup> GetInnerMockSetups()
		{
			return this.ToArrayLive(setup => setup.ReturnsInnerMock(out _));
		}

		public Setup[] ToArrayLive(Func<Setup, bool> predicate)
		{
			var matchingSetups = new Stack<Setup>();
			var visitedSetups = new HashSet<InvocationShape>();

			lock (this.setups)
			{
				// Iterating in reverse order because newer setups are more relevant than (i.e. override) older ones
				for (int i = this.setups.Count - 1; i >= 0; --i)
				{
					if (i < 32 && (this.overridden & (1U << i)) != 0) continue;

					var setup = this.setups[i];

					if (setup.Condition != null)
					{
						continue;
					}

					if (!visitedSetups.Add(setup.Expectation))
					{
						// A setup with the same expression has already been iterated over,
						// meaning that this older setup is an overridden one.
						if (i < 32) this.overridden |= 1U << i;
						continue;
					}

					if (predicate(setup))
					{
						matchingSetups.Push(setup);
{'fraction_non_alphanumeric': 0.1140852870592579, 'fraction_numerical': 0.0064611408528705925, 'mean_word_length': 2.557452396585686, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4120938', 'n_tokens_mistral': 2273, 'n_tokens_neox': 1697, 'n_words': 508}