protected override Action? ExecutePsiTransaction()

in resharper/resharper-unity/src/Unity/CSharp/Feature/Services/ContextActions/AddFieldToExistingBakerAndAuthoringAction.cs [88:176]


        protected override Action<ITextControl>? ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
        {
            var (bakerBaseTypeElement, _) = TypeFactory.CreateTypeByCLRName(KnownTypes.Baker,
                NullableAnnotation.Unknown, myFieldDeclaration.GetPsiModule());
            var bakers = new List<ITypeElement>();

            var psiServices = solution.GetPsiServices();
            var finder = psiServices.Finder;
            progress.Start(3);

            using (var spi = new SubProgressIndicator(progress, 1))
            {
                finder.FindInheritors(bakerBaseTypeElement, bakers.ConsumeDeclaredElements(), spi);
            }

            if (bakers.Count == 0)
            {
                return textControl =>
                {
                    ShowTooltip(textControl, Strings.UnityDots_AddFieldToExistingBakerAndAuthoring_NoBakersFound);
                };
            }

            var componentDeclaredElement = myFieldDeclaration.GetContainingTypeDeclaration()?.DeclaredElement;
            if (componentDeclaredElement == null)
                return null;

            IReference[]? componentReferences;
            using (var spi = new SubProgressIndicator(progress, 1))
            {
                componentReferences = finder.FindReferences(componentDeclaredElement, bakers.UnionSearchDomains(), spi);
            }

            if (componentReferences.IsEmpty())
            {
                return textControl =>
                {
                    ShowTooltip(textControl, string.Format(Strings.UnityDots_AddFieldToExistingBakerAndAuthoring_NoBakersForComponent, componentDeclaredElement.ShortName));
                };
            }
            using (var spi = new SubProgressIndicator(progress, 1))
            {
                spi.Start(componentReferences.Length);
                for (var index = 0; index < componentReferences.Length; index++)
                {
                    spi.Advance(index);

                    var componentReference = componentReferences[index];

                    var addComponentExpression =
                        componentReference.GetTreeNode().GetContainingNode<IInvocationExpression>();
                    if (addComponentExpression == null)
                        continue;

                    if (!addComponentExpression.IsIBakerAddComponentMethod() &&
                        !addComponentExpression.IsIBakerAddComponentObjectMethod())
                        continue;

                    var bakerClassLikeDeclaration = addComponentExpression.GetContainingNode<IClassLikeDeclaration>();

                    var selectedBaker = bakerClassLikeDeclaration?.DeclaredElement;

                    if (selectedBaker == null)
                        continue;

                    var selectedAuthoringComponent =
                        GenerateBakerAndAuthoringActionBuilder.GetSelectedAuthoringComponent(selectedBaker);

                    if (selectedAuthoringComponent == null)
                        continue;

                    var factory = CSharpElementFactory.GetInstance(addComponentExpression);

                    var generationParameters = new GenerateBakerAndAuthoringActionBuilder.GenerationParameters(
                        new List<IField> { myFieldDeclaration.DeclaredElement },
                        myComponentClassDeclaration,
                        selectedAuthoringComponent,
                        selectedBaker,
                        true,
                        factory,
                        addComponentExpression.PsiModule,
                        false);

                    GenerateBakerAndAuthoringActionBuilder.GenerateBakerAndAuthoring(generationParameters);
                }
            }

            return null;
        }