Beispiel #1
0
        private bool HasAnyExactMatchInheritedMethods(IEnumerable <TypeMemberInstance <IMethod> > inheritedMethods,
                                                      UnityEventFunction function)
        {
            foreach (var existingMethod in inheritedMethods)
            {
                if (function.Match(existingMethod.Member) == MethodSignatureMatch.ExactMatch)
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool HasAnyPartiallyMatchingExistingMethods(List <IMethod> existingMethods, UnityEventFunction function)
        {
            // Don't use Any() - it's surprisingly expensive when called for each function we're adding to the lookup list
            foreach (var existingMethod in existingMethods)
            {
                if (function.Match(existingMethod) != MethodSignatureMatch.NoMatch)
                {
                    return(true);
                }
            }

            return(false);
        }
        private void Accept(ITextControl textControl, IRangeMarker rangeMarker, ISolution solution)
        {
            var identifierNode = TextControlToPsi.GetElement <ITreeNode>(solution, textControl);
            var psiServices    = solution.GetPsiServices();

            if (identifierNode != null)
            {
                IErrorElement errorElement;

                ITreeNode usage = identifierNode.GetContainingNode <IUserTypeUsage>();
                if (usage != null)
                {
                    errorElement = usage.NextSibling as IErrorElement;
                }
                else
                {
                    usage = identifierNode.PrevSibling;
                    while (usage != null && !(usage is ITypeUsage))
                    {
                        usage = usage.PrevSibling;
                    }
                    errorElement = identifierNode.NextSibling as IErrorElement;
                }

                using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveIdentifier"))
                    using (new DisableCodeFormatter())
                    {
                        using (WriteLockCookie.Create())
                        {
                            ModificationUtil.DeleteChild(identifierNode);
                            if (usage != null)
                            {
                                ModificationUtil.DeleteChild(usage);
                            }
                            if (errorElement != null)
                            {
                                ModificationUtil.DeleteChild(errorElement);
                            }
                        }

                        cookie.Commit();
                    }
            }

            using (WriteLockCookie.Create())
            {
                textControl.Document.InsertText(rangeMarker.DocumentRange.StartOffset, "void Foo(){}");
            }

            psiServices.Files.CommitAllDocuments();

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

            if (methodDeclaration == null)
            {
                return;
            }

            var insertionIndex = methodDeclaration.GetTreeStartOffset().Offset;

            string attributeText = null;

            var attributeList = methodDeclaration.FirstChild as IAttributeSectionList;

            if (attributeList != null)
            {
                attributeText = attributeList.GetText();
                var treeNode = attributeList.NextSibling;
                while (treeNode is IWhitespaceNode)
                {
                    attributeText += treeNode.GetText();
                    treeNode       = treeNode.NextSibling;
                }
            }

            using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveInsertedDeclaration"))
                using (new DisableCodeFormatter())
                {
                    using (WriteLockCookie.Create())
                        ModificationUtil.DeleteChild(methodDeclaration);

                    cookie.Commit();
                }

            // Get the UnityEventFunction generator to actually insert the methods
            GenerateCodeWorkflowBase.ExecuteNonInteractive(
                GeneratorUnityKinds.UnityEventFunctions, solution, textControl, methodDeclaration.Language,
                configureContext: context =>
            {
                var inputElements = from e in context.ProvidedElements.Cast <GeneratorDeclaredElement <IMethod> >()
                                    where myEventFunction.Match(e.DeclaredElement) != EventFunctionMatch.NoMatch
                                    select e;

                context.InputElements.Clear();
                context.InputElements.AddRange(inputElements);
            });

            if (!string.IsNullOrEmpty(attributeText))
            {
                using (WriteLockCookie.Create())
                    textControl.Document.InsertText(insertionIndex, attributeText);
            }
        }
Beispiel #4
0
        private void Accept(ITextControl textControl, IRangeMarker rangeMarker, ISolution solution)
        {
            var psiServices = solution.GetPsiServices();

            // Get the node at the caret. This will be the identifier
            var identifierNode = TextControlToPsi.GetElement <ITreeNode>(solution, textControl);

            if (identifierNode == null)
            {
                return;
            }

            // Delete the half completed identifier node. Also delete any explicitly entered
            // return type, as our declared element will create one anyway
            if (!(identifierNode.GetPreviousMeaningfulSibling() is ITypeUsage typeUsage))
            {
                // E.g. `void OnAnim{caret} [SerializeField]...` This is parsed as a field with an array specifier
                var fieldDeclaration = identifierNode.GetContainingNode <IFieldDeclaration>();
                typeUsage = fieldDeclaration?.GetPreviousMeaningfulSibling() as ITypeUsage;
            }

            using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveIdentifier"))
                using (new DisableCodeFormatter())
                {
                    using (WriteLockCookie.Create())
                    {
                        ModificationUtil.DeleteChild(identifierNode);
                        if (typeUsage != null)
                        {
                            ModificationUtil.DeleteChild(typeUsage);
                        }
                    }

                    cookie.Commit();
                }

            // 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.InsertText(rangeMarker.DocumentRange.StartOffset, "void Foo(){}");

            psiServices.Files.CommitAllDocuments();

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

            if (methodDeclaration == null)
            {
                return;
            }

            var attributeList = methodDeclaration.FirstChild as IAttributeSectionList;

            using (var cookie = new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "RemoveInsertedDeclaration"))
                using (new DisableCodeFormatter())
                {
                    using (WriteLockCookie.Create())
                        ModificationUtil.DeleteChild(methodDeclaration);
                    cookie.Commit();
                }

            // Get the UnityEventFunction generator to actually insert the methods
            GenerateCodeWorkflowBase.ExecuteNonInteractive(
                GeneratorUnityKinds.UnityEventFunctions, solution, textControl, identifierNode.Language,
                configureContext: context =>
            {
                var inputElements = from e in context.ProvidedElements.Cast <GeneratorDeclaredElement <IMethod> >()
                                    where myEventFunction.Match(e.DeclaredElement) != MethodSignatureMatch.NoMatch
                                    select e;

                context.InputElements.Clear();
                context.InputElements.AddRange(inputElements);
            });

            if (attributeList != null)
            {
                methodDeclaration = TextControlToPsi.GetElement <IMethodDeclaration>(solution, textControl);
                if (methodDeclaration != null)
                {
                    using (var transactionCookie =
                               new PsiTransactionCookie(psiServices, DefaultAction.Rollback, "InsertAttributes"))
                    {
                        methodDeclaration.SetAttributeSectionList(attributeList);
                        transactionCookie.Commit();
                    }
                }
            }
        }