예제 #1
0
        /// <summary>
        /// Add a using directive.
        /// </summary>
        /// <param name="compilationUnit">The <see cref="CompilationUnitSyntax"/>.</param>
        /// <param name="usingDirective">The <see cref="UsingDirectiveSyntax"/>.</param>
        /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param>
        /// <returns>The updated <see cref="CompilationUnitSyntax"/>.</returns>
        public static CompilationUnitSyntax AddUsing(this CompilationUnitSyntax compilationUnit, UsingDirectiveSyntax usingDirective, SemanticModel semanticModel)
        {
            if (compilationUnit is null)
            {
                throw new System.ArgumentNullException(nameof(compilationUnit));
            }

            if (semanticModel is null)
            {
                throw new System.ArgumentNullException(nameof(semanticModel));
            }

            if (usingDirective is null)
            {
                throw new System.ArgumentNullException(nameof(usingDirective));
            }

            if (compilationUnit.Members.TrySingleOfType <MemberDeclarationSyntax, NamespaceDeclarationSyntax>(out NamespaceDeclarationSyntax? ns) &&
                UsingDirectiveComparer.IsSameOrContained(ns, usingDirective))
            {
                return(compilationUnit);
            }

            using (var walker = UsingDirectiveWalker.Borrow(compilationUnit))
            {
                if (walker.UsingDirectives.Count == 0)
                {
                    if (walker.NamespaceDeclarations.TryFirst(out var namespaceDeclaration))
                    {
                        if (CodeStyle.UsingDirectivesInsideNamespace(semanticModel) != CodeStyleResult.No)
                        {
                            return(compilationUnit.ReplaceNode(namespaceDeclaration, namespaceDeclaration.WithUsings(SyntaxFactory.SingletonList(usingDirective))));
                        }

                        return(compilationUnit.ReplaceNode(compilationUnit, compilationUnit.WithUsings(SyntaxFactory.SingletonList(usingDirective))));
                    }

                    return(compilationUnit);
                }

                UsingDirectiveSyntax?previous = null;
                foreach (var directive in walker.UsingDirectives)
                {
                    var compare = UsingDirectiveComparer.Compare(directive, usingDirective);
                    if (compare == 0)
                    {
                        return(compilationUnit);
                    }

                    if (compare > 0)
                    {
                        return(compilationUnit.InsertNodesBefore(directive, new[] { usingDirective.WithTrailingElasticLineFeed() }));
                    }

                    previous = directive;
                }

                return(compilationUnit.InsertNodesAfter(previous, new[] { usingDirective.WithTrailingElasticLineFeed() }));
            }
        }