internal static bool TryGetCreateClassSymbol(
     this Project testProject, BuilderCopSettings builderCopSettings, out ITypeSymbol createClassSymbol)
 {
     createClassSymbol = SymbolFinder.FindDeclarationsAsync(testProject, builderCopSettings.BuilderFactorySettings.Name, false, SymbolFilter.Type)
                         .Result.FirstOrDefault() as ITypeSymbol;
     return(createClassSymbol != null);
 }
        public void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            BuilderCopSettings builderCopSettings = context.Options.GetBuilderCopSettings(new CancellationToken());

            INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            if (!namedTypeSymbol.ShouldTypeHaveBuilder(builderCopSettings.BuilderForSettings))
            {
                return;
            }

            INamedTypeSymbol builderSymbol;

            if (!namedTypeSymbol.TryGetTestDataBuilder(builderCopSettings, out builderSymbol))
            {
                context.ReportTypeShouldHaveBuilderDiagnostic(namedTypeSymbol);
            }
            else
            {
                AnalyseFactory(context, namedTypeSymbol.GetAccordingTestProject(), builderSymbol, builderCopSettings);
                AnalyseBuilder(context, builderSymbol, namedTypeSymbol);
            }
        }
        internal static bool TryGetTestDataBuilder(this INamedTypeSymbol namedTypeSymbol, BuilderCopSettings builderCopSettings, out INamedTypeSymbol builderSymbol)
        {
            Project         testProject = namedTypeSymbol.GetAccordingTestProject();
            IList <ISymbol> foundBuilderDeclarations = SymbolFinder.FindDeclarationsAsync(testProject, namedTypeSymbol.Name + "Builder", true).Result.ToList();

            builderSymbol = foundBuilderDeclarations.OfType <INamedTypeSymbol>().FirstOrDefault();

            return(builderSymbol != null);
        }
        internal static INamedTypeSymbol GetTestDataBuilder(this INamedTypeSymbol namedTypeSymbol, BuilderCopSettings builderCopSettings)
        {
            INamedTypeSymbol builderSymbol;

            if (TryGetTestDataBuilder(namedTypeSymbol, builderCopSettings, out builderSymbol))
            {
                return(builderSymbol);
            }
            else
            {
                return(null);
            }
        }
        internal static ITypeSymbol GetBuilderFactorySymbol(this Project testProject, BuilderCopSettings builderCopSettings)
        {
            ITypeSymbol createClassTypeSymbol;

            if (testProject.TryGetCreateClassSymbol(builderCopSettings, out createClassTypeSymbol))
            {
                return(createClassTypeSymbol);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        ///     Überprüft, ob es eine Create-Klasse gibt, die eine Instanz des Builders erzeugen kann.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="testProject"></param>
        /// <param name="builderSymbol"></param>
        /// <param name="builderCopSettings"></param>
        private void AnalyseFactory(SymbolAnalysisContext context, Project testProject, INamedTypeSymbol builderSymbol, BuilderCopSettings builderCopSettings)
        {
            ITypeSymbol createClassSymbol = testProject.GetBuilderFactorySymbol(builderCopSettings);

            if (createClassSymbol == null)
            {
                return;
            }

            foreach (IMethodSymbol method in createClassSymbol.GetMembers().OfType <IMethodSymbol>())
            {
                if (method.MethodKind == MethodKind.Ordinary && TypeHelper.AreTypesEqual(method.ReturnType, builderSymbol))
                {
                    return;
                }
            }

            /* Die Diagnostic geht auf die Entity-Klasse, weil dass die Klasse ist, die untersucht wird.
             * Wird die Location auf den Builder gelegt, fliegt eine Exception, da der Builder nicht Teil des Kompilats ist,
             * welches analysiert wird.*/
            context.ReportFactoryMethodForBuilderExpected(context.Symbol);
        }