Repository: dotnet/roslyn
File: src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs (C#)

Code before:
                if (parentNode is null)
                {
                    return false;
                }

                var kind = parentNode.Kind();
                switch (kind)
                {
                    case SyntaxKind.IfDirectiveTrivia:
                        {
                            var parentIf = (IfDirectiveTriviaSyntax)parentNode;
                            return parentIf.Condition.FullSpan.Contains(node.FullSpan);
                        }
                    case SyntaxKind.ElifDirectiveTrivia:
                        {
                            var parentElif = (ElifDirectiveTriviaSyntax)parentNode;
                            return parentElif.Condition.FullSpan.Contains(node.FullSpan);
                        }
                }

                if (SyntaxFacts.IsPreprocessorDirective(kind))
                {
                    return false;
                }

                return isPreprocessingSymbolIdentifierContainer(parentNode.Parent);
            }
        }

        /// <summary>
        /// Options to control the internal working of GetSymbolInfoWorker. Not currently exposed
        /// to public clients, but could be if desired.
        /// </summary>
        [Flags]
        internal enum SymbolInfoOptions
        {
            /// <summary>
            /// When binding "C" new C(...), return the type C and do not return information about
            /// which constructor was bound to. Bind "new C(...)" to get information about which constructor
            /// was chosen.
            /// </summary>
            PreferTypeToConstructors = 0x1,

            /// <summary>
            /// When binding "C" new C(...), return the constructor of C that was bound to, if C unambiguously
            /// binds to a single type with at least one constructor. 
            /// </summary>
            PreferConstructorsToType = 0x2,

            /// <summary>
            /// When binding a name X that was declared with a "using X=OtherTypeOrNamespace", return OtherTypeOrNamespace.

Review comment (suggestion):
>return isPreprocessingSymbolIdentifierContainer(parentNode.Parent); [](http://example.com/codeflow?start=16&length=67)

It looks like we could use a `while` loop instead of a recursion. #Closed

Code after:
                var parentNode = node.Parent;
                while (parentNode is not null)
                {
                    var kind = parentNode.Kind();
                    switch (kind)
                    {
                        case SyntaxKind.IfDirectiveTrivia:
                            {
                                var parentIf = (IfDirectiveTriviaSyntax)parentNode;
                                return parentIf.Condition.FullSpan.Contains(node.FullSpan);
                            }
                        case SyntaxKind.ElifDirectiveTrivia:
                            {
                                var parentElif = (ElifDirectiveTriviaSyntax)parentNode;
                                return parentElif.Condition.FullSpan.Contains(node.FullSpan);
                            }
                    }

                    if (SyntaxFacts.IsPreprocessorDirective(kind))
                    {
                        return false;
                    }

                    parentNode = parentNode.Parent;
                }
                return false;
            }
        }

        /// <summary>
        /// Options to control the internal working of GetSymbolInfoWorker. Not currently exposed
        /// to public clients, but could be if desired.
        /// </summary>
        [Flags]
        internal enum SymbolInfoOptions
        {
            /// <summary>
            /// When binding "C" new C(...), return the type C and do not return information about
            /// which constructor was bound to. Bind "new C(...)" to get information about which constructor
            /// was chosen.
            /// </summary>
            PreferTypeToConstructors = 0x1,

            /// <summary>
            /// When binding "C" new C(...), return the constructor of C that was bound to, if C unambiguously
            /// binds to a single type with at least one constructor. 
            /// </summary>
            PreferConstructorsToType = 0x2,

            /// <summary>
            /// When binding a name X that was declared with a "using X=OtherTypeOrNamespace", return OtherTypeOrNamespace.