public override void Accept()

in resharper/resharper-unity/src/Unity/CSharp/Feature/Services/CodeCompletion/UnityEventFunctionBehavior.cs [43:132]


        public override void Accept(
            ITextControl textControl, DocumentRange nameRange,
            LookupItemInsertType insertType, Suffix suffix, ISolution solution, bool keepCaretStill)
        {
            var psiServices = solution.GetPsiServices();
            var updateMethodDeclaration = TextControlToPsi.GetElement<IMethodDeclaration>(solution, textControl);
            if (!Info.ShouldGenerateMethod)
            {
                UpdateExistingMethod(updateMethodDeclaration, nameRange, textControl, psiServices);
                return;
            }

            var isCoroutine = updateMethodDeclaration?.TypeUsage is IUserTypeUsage userTypeUsage &&
                              userTypeUsage.ScalarTypeName?.ShortName == "IEnumerator";

            var fixedNameRange = nameRange.SetStartTo(Info.MemberReplaceRanges.InsertRange.StartOffset);
            var memberRange = Info.MemberReplaceRanges.GetAcceptRange(fixedNameRange, insertType);

            // Insert a dummy method declaration, as text, which means the PSI is reparsed. This will remove empty type
            // usages and merge leading attributes into a method declaration, such that we can copy them and replace
            // them once the declared element has expanded. This also fixes up the case where the type usage picks up
            // the attribute of the next code construct as an array specifier. E.g. `OnAni{caret} [SerializeField]`
            using (WriteLockCookie.Create())
            {
                textControl.Document.ReplaceText(memberRange, "void Foo(){}");
            }

            psiServices.Files.CommitAllDocuments();

            var methodDeclaration = TextControlToPsi.GetElement<IMethodDeclaration>(solution, textControl);
            if (methodDeclaration == null) return;

            var methodDeclarationCopy = methodDeclaration.Copy();
            var nodesBeforeCopyRange = NodesBeforeMethodHeader(methodDeclarationCopy);

            using (new PsiTransactionCookie(psiServices, DefaultAction.Commit, "RemoveInsertedDeclaration"))
            using (WriteLockCookie.Create())
            {
                LowLevelModificationUtil.DeleteChild(methodDeclaration);
            }

            var classDeclaration = TextControlToPsi.GetElement<IClassLikeDeclaration>(solution, textControl);
            Assertion.AssertNotNull(classDeclaration, "classDeclaration != null");

            var factory = CSharpElementFactory.GetInstance(classDeclaration);

            GenerateCodeWorkflowBase.ExecuteNonInteractive(
                GeneratorUnityKinds.UnityEventFunctions, solution, textControl, methodDeclaration.Language,
                configureContext: context =>
                {
                    // Note that the generated code will use the access rights, if specified. However, if they haven't
                    // been specified (NONE) or they are the default for methods (PRIVATE), the generated code will be
                    // whatever the current code style setting is - implicit or explicit
                    var knownTypesCache = solution.GetComponent<KnownTypesCache>();
                    var declaredElement = myEventFunction.CreateDeclaration(factory, knownTypesCache, classDeclaration,
                            myAccessRights, makeCoroutine: isCoroutine)
                        .DeclaredElement.NotNull("declaredElement != null");
                    context.InputElements.Clear();
                    context.InputElements.Add(new GeneratorDeclaredElement(declaredElement));
                },
                onCompleted: context =>
                {
                    if (nodesBeforeCopyRange.IsEmpty) return;

                    foreach (var outputElement in context.OutputElements)
                    {
                        if (outputElement is GeneratorDeclarationElement declarationElement)
                        {
                            using (new PsiTransactionCookie(psiServices, DefaultAction.Commit, "BringBackAttributes"))
                            using (WriteLockCookie.Create())
                            {
                                var newDeclaration = declarationElement.Declaration;
                                ModificationUtil.AddChildRangeAfter(newDeclaration, anchor: null, nodesBeforeCopyRange);
                            }

                            return;
                        }
                    }
                });

            ITreeRange NodesBeforeMethodHeader(IMethodDeclaration declaration)
            {
                var firstNode = declaration.ModifiersList ?? declaration.TypeUsage as ITreeNode;

                var smthBeforeTypeUsage = firstNode?.PrevSibling;
                if (smthBeforeTypeUsage == null) return TreeRange.Empty;

                return new TreeRange(declaration.FirstChild, smthBeforeTypeUsage);
            }
        }