<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AsyncGenerator.Core;
using AsyncGenerator.Core.Analyzation;
using AsyncGenerator.Core.Configuration;
using AsyncGenerator.Core.Plugins;
using AsyncGenerator.Core.Transformation;
using AsyncGenerator.Extensions.Internal;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace AsyncGenerator.Plugins.Internal
{
	internal class ParallelForForEachTransformer : AbstractPlugin,
		IAsyncCounterpartsFinder,
		IFunctionReferenceTransformer,
		IInvocationExpressionAnalyzer,
		IBodyFunctionReferencePostAnalyzer
	{
		private IMethodSymbol _whenAllMethod;
		private IMethodSymbol _forEachMethod;
		private IMethodSymbol _forMethod;

		public override Task Initialize(Project project, IProjectConfiguration configuration, Compilation compilation)
		{
			var taskSymbol =
				compilation.References
					.Select(compilation.GetAssemblyOrModuleSymbol)
					.OfType<IAssemblySymbol>()
					.Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName("System.Threading.Tasks.Task"))
					.FirstOrDefault(o => o != null);
			if (taskSymbol == null)
			{
				throw new InvalidOperationException("Unable to find System.Threading.Tasks.Task type");
			}
			// Get member:
			// Task WhenAll(IEnumerable<Task> tasks)
			_whenAllMethod = taskSymbol.GetMembers("WhenAll").OfType<IMethodSymbol>()
				.First(o => o.Parameters.Length == 1 &&
				            !o.IsGenericMethod &&
				            !o.Parameters[0].IsParams);

			var parallelSymbol =
				compilation.References
					.Select(compilation.GetAssemblyOrModuleSymbol)
					.OfType<IAssemblySymbol>()
					.Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName("System.Threading.Tasks.Parallel"))
					.FirstOrDefault(o => o != null);
			if (parallelSymbol == null)
			{
				return Task.CompletedTask;
			}

			// Try to get member:
			// ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)
			_forEachMethod = parallelSymbol.GetMembers("ForEach").OfType<IMethodSymbol>()
				.FirstOrDefault(o =>
					o.Parameters.Length == 2 &&
					o.Parameters[1].Type is INamedTypeSymbol namedType &&
					namedType.IsGenericType &&<commit_msg>Fixed ParallelForEach tests on Unix<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AsyncGenerator.Core;
using AsyncGenerator.Core.Analyzation;
using AsyncGenerator.Core.Configuration;
using AsyncGenerator.Core.Plugins;
using AsyncGenerator.Core.Transformation;
using AsyncGenerator.Extensions.Internal;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace AsyncGenerator.Plugins.Internal
{
	internal class ParallelForForEachTransformer : AbstractPlugin,
		IAsyncCounterpartsFinder,
		IFunctionReferenceTransformer,
		IInvocationExpressionAnalyzer,
		IBodyFunctionReferencePostAnalyzer
	{
		private IMethodSymbol _whenAllMethod;
		private IMethodSymbol _forEachMethod;
		private IMethodSymbol _forMethod;

		public override Task Initialize(Project project, IProjectConfiguration configuration, Compilation compilation)
		{
			var taskSymbol =
				compilation.References
					.Select(compilation.GetAssemblyOrModuleSymbol)
					.OfType<IAssemblySymbol>()
					.Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName("System.Threading.Tasks.Task"))
					.FirstOrDefault(o => o != null);
			if (taskSymbol == null)
			{
				throw new InvalidOperationException("Unable to find System.Threading.Tasks.Task type");
			}
			// Get member:
			// Task WhenAll(IEnumerable<Task> tasks)
			_whenAllMethod = taskSymbol.GetMembers("WhenAll").OfType<IMethodSymbol>()
				.First(o => o.Parameters.Length == 1 &&
				            !o.IsGenericMethod &&
				            !o.Parameters[0].IsParams);

			var parallelSymbol =
				compilation.References
					.Select(compilation.GetAssemblyOrModuleSymbol)
					.OfType<IAssemblySymbol>()
					.Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName("System.Threading.Tasks.Parallel"))
					.FirstOrDefault(o => o != null);
			if (parallelSymbol == null)
			{
				return Task.CompletedTask;
			}

			// Try to get member:
			// ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)
			_forEachMethod = parallelSymbol.GetMembers("ForEach").OfType<IMethodSymbol>()
				.FirstOrDefault(o =>
					o.Parameters.Length == 2 &&
					o.Parameters[0].Type.Name == "IEnumerable" &&
					o.Parameters[1].Type is INamedTypeSymbol namedType &&
					namedType.IsGenericType &&
{'fraction_non_alphanumeric': 0.09876801002296931, 'fraction_numerical': 0.0018793067446230946, 'mean_word_length': 4.764139590854392, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 31, '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': '7322377', 'n_tokens_mistral': 1540, 'n_tokens_neox': 1314, 'n_words': 252}