internal static string GenerateMutualSafeRec(GeneratorExecutionContext context, IReadOnlyList <RecursiveMethodInfo> methodInfos) { var firstMethodInfo = methodInfos.First(); if (string.IsNullOrEmpty(firstMethodInfo.CodeGenProps.MutualRecursionId)) { throw new ArgumentException($"Empty {nameof(SafeRecursionCodeGenProps.MutualRecursionId)} in the first methodInfo of {nameof(methodInfos)}."); } if (methodInfos.Count == 1) { // Warn the user but continue anyway as we should generate a working code anyway if there // is actually exactly 1 MutualRecursionId. The code will be slower but it should work. context.ReportConfigurationWarning(firstMethodInfo.MethodSyntax, $"Suspiciously only one method is found for the mutual recursive group '{firstMethodInfo.CodeGenProps.MutualRecursionId}'"); } // TODO really check that all GenericParams and ConstraintClauses for all methodInfos are // the same. If it is not so, the compilation probably will fail anyway but the message will // not be very user-friendly foreach (var methodInfo in methodInfos) { if ((methodInfo.GenericParams != firstMethodInfo.GenericParams) || (methodInfo.ConstraintClauses != firstMethodInfo.ConstraintClauses)) { // string equality check is not really correct so only generate a warning context.ReportConfigurationWarning(methodInfo.MethodSyntax, $"Suspiciously generic methods '{firstMethodInfo.MethodName}' and '{methodInfo.MethodName}' have differently looking generic params" + $" '{firstMethodInfo.GenericParams}' '{firstMethodInfo.ConstraintClauses}'" + $" != '{methodInfo.GenericParams}' '{methodInfo.ConstraintClauses}'"); } } var classSyntax = (ClassDeclarationSyntax)firstMethodInfo.MethodSyntax.Parent; var classSymbol = firstMethodInfo.MethodSymbol.ContainingType; var recursionId = firstMethodInfo.CodeGenProps.MutualRecursionId; var classInfo = new RecursiveCalculatorClassInfo(classSyntax, classSymbol, isMultiSite: true, recursionId, firstMethodInfo.GenericParams, firstMethodInfo.ConstraintClauses, paramsStructName: recursionId + RecursiveCalculatorClassInfo.DispatchStructSuffix); return(new CalculatorClassGenerator(context, classInfo, methodInfos).GenerateAll()); }