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

Code before:
        /// 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.
            /// </summary>
            ResolveAliases = 0x4,

            /// <summary>
            /// When binding a name X that was declared with a "using X=OtherTypeOrNamespace", return the alias symbol X.
            /// </summary>
            PreserveAliases = 0x8,

            // Default Options.
            DefaultOptions = PreferConstructorsToType | ResolveAliases
        }

        internal static void ValidateSymbolInfoOptions(SymbolInfoOptions options)
        {
            Debug.Assert(((options & SymbolInfoOptions.PreferConstructorsToType) != 0) !=
                         ((options & SymbolInfoOptions.PreferTypeToConstructors) != 0), "Options are mutually exclusive");
            Debug.Assert(((options & SymbolInfoOptions.ResolveAliases) != 0) !=
                         ((options & SymbolInfoOptions.PreserveAliases) != 0), "Options are mutually exclusive");
        }

        /// <summary>
        /// Given a position in the SyntaxTree for this SemanticModel returns the innermost
        /// NamedType that the position is considered inside of.
        /// </summary>
        public ISymbol GetEnclosingSymbol(int position)
        {
            position = CheckAndAdjustPosition(position);
            var binder = GetEnclosingBinder(position);
            return binder == null ? null : binder.ContainingMemberOrLambda.GetPublicSymbol();
        }

Review comment (suggestion):
```suggestion
                for (var parentNode = node.Parent; parentNode != null; parentNode = parentNode.Parent)
                {
                    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 false;
```

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.