Exemple #1
0
        /// <summary>
        /// Inserts 'newUsing' in the current scope.
        /// This method will try to insert new usings in the correct position (depending on
        /// where the existing usings are; and maintaining the sort order).
        /// </summary>
        public static void InsertUsing(RefactoringContext context, Script script, AstNode newUsing)
        {
            UsingInfo newUsingInfo       = new UsingInfo(newUsing, context);
            AstNode   enclosingNamespace = context.GetNode <NamespaceDeclaration>() ?? context.RootNode;
            // Find nearest enclosing parent that has usings:
            AstNode usingParent = enclosingNamespace;

            while (usingParent != null && !usingParent.Children.OfType <UsingDeclaration>().Any())
            {
                usingParent = usingParent.Parent;
            }
            if (usingParent == null)
            {
                // No existing usings at all -> use the default location
                if (script.FormattingOptions.UsingPlacement == UsingPlacement.TopOfFile)
                {
                    usingParent = context.RootNode;
                }
                else
                {
                    usingParent = enclosingNamespace;
                }
            }
            // Find the main block of using declarations in the chosen scope:
            AstNode blockStart = usingParent.Children.FirstOrDefault(IsUsingDeclaration);
            AstNode insertionPoint;
            bool    insertAfter = false;

            if (blockStart == null)
            {
                // no using declarations in the file
                Debug.Assert(SyntaxTree.MemberRole == NamespaceDeclaration.MemberRole);
                insertionPoint = usingParent.GetChildrenByRole(SyntaxTree.MemberRole).SkipWhile(CanAppearBeforeUsings).FirstOrDefault();
            }
            else
            {
                insertionPoint = blockStart;
                while (IsUsingFollowing(ref insertionPoint) && newUsingInfo.CompareTo(new UsingInfo(insertionPoint, context)) > 0)
                {
                    insertionPoint = insertionPoint.NextSibling;
                }
                if (!IsUsingDeclaration(insertionPoint))
                {
                    // Insert after last using instead of before next node
                    // This affects where empty lines get placed.
                    insertionPoint = insertionPoint.PrevSibling;
                    insertAfter    = true;
                }
            }
            if (insertionPoint != null)
            {
                if (insertAfter)
                {
                    script.InsertAfter(insertionPoint, newUsing);
                }
                else
                {
                    script.InsertBefore(insertionPoint, newUsing);
                }
            }
        }