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

Code before:

        /// <summary>
        /// Gets await expression info.
        /// </summary>
        /// <param name="node">The node.</param>
        public abstract AwaitExpressionInfo GetAwaitExpressionInfo(AwaitExpressionSyntax node);

        /// <summary>
        /// If the given node is within a preprocessing directive, gets the preprocessing symbol info for it.
        /// </summary>
        /// <param name="node">Preprocessing symbol identifier node.</param>
        public PreprocessingSymbolInfo GetPreprocessingSymbolInfo(IdentifierNameSyntax node)
        {
            CheckSyntaxNode(node);

            if (node.Ancestors().Any(n => isPreprocessorDirectiveAcceptingPreprocessingSymbols(n.Kind())))
            {
                bool isDefined = this.SyntaxTree.IsPreprocessorSymbolDefined(node.Identifier.ValueText, node.Identifier.SpanStart);
                return new PreprocessingSymbolInfo(new Symbols.PublicModel.PreprocessingSymbol(node.Identifier.ValueText), isDefined);
            }

            return PreprocessingSymbolInfo.None;

            static bool isPreprocessorDirectiveAcceptingPreprocessingSymbols(SyntaxKind kind)
            {
                switch (kind)
                {
                    case SyntaxKind.IfDirectiveTrivia:
                    case SyntaxKind.ElifDirectiveTrivia:
                    case SyntaxKind.DefineDirectiveTrivia:
                    case SyntaxKind.UndefDirectiveTrivia:
                        return true;
                    default:
                        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,

Review comment (suggestion):
```suggestion
                => kind is SyntaxKind.IfDirectiveTrivia or SyntaxKind.ElifDirectiveTrivia or SyntaxKind.DefineDirectiveTrivia or SyntaxKind.UndefDirectiveTrivia;
```

Code after:
        public abstract AwaitExpressionInfo GetAwaitExpressionInfo(LocalDeclarationStatementSyntax node);

        /// <summary>
        /// Gets await expression info.
        /// </summary>
        /// <param name="node">The node.</param>
        public abstract AwaitExpressionInfo GetAwaitExpressionInfo(UsingStatementSyntax node);

        /// <summary>
        /// If the given node is within a preprocessing directive, gets the preprocessing symbol info for it.
        /// </summary>
        /// <param name="node">Preprocessing symbol identifier node.</param>
        public PreprocessingSymbolInfo GetPreprocessingSymbolInfo(IdentifierNameSyntax node)
        {
            CheckSyntaxNode(node);

            if (isPossiblePreprocessingSymbolReference(node))
            {
                bool isDefined = this.SyntaxTree.IsPreprocessorSymbolDefined(node.Identifier.ValueText, node.Identifier.SpanStart);
                return new PreprocessingSymbolInfo(new Symbols.PublicModel.PreprocessingSymbol(node.Identifier.ValueText), isDefined);
            }

            return PreprocessingSymbolInfo.None;

            bool isPossiblePreprocessingSymbolReference(IdentifierNameSyntax node)
            {
                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;
                }