<commit_before>﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Simplification;

namespace Microsoft.CodeAnalysis.CSharp.Simplification
{
    internal abstract partial class AbstractCSharpReducer
    {
        protected abstract class AbstractReductionRewriter : CSharpSyntaxRewriter, IReductionRewriter
        {
            private readonly ObjectPool<IReductionRewriter> _pool;

            protected CSharpParseOptions ParseOptions { get; private set; }
            protected OptionSet OptionSet { get; private set; }
            protected CancellationToken CancellationToken { get; private set; }
            protected SemanticModel SemanticModel { get; private set; }

            public bool HasMoreWork { get; private set; }

            // can be used to simplify whole subtrees while just annotating one syntax node.
            // This is e.g. useful in the name simplification, where a whole qualified name is annotated
            protected bool alwaysSimplify;

            private readonly HashSet<SyntaxNode> _processedParentNodes = new HashSet<SyntaxNode>();

            protected AbstractReductionRewriter(ObjectPool<IReductionRewriter> pool)
                => _pool = pool;

            public void Initialize(ParseOptions parseOptions, OptionSet optionSet, CancellationToken cancellationToken)
            {
                ParseOptions = (CSharpParseOptions)parseOptions;
                OptionSet = optionSet;
                CancellationToken = cancellationToken;
            }

            public void Dispose()
            {
                ParseOptions = null;
                OptionSet = null;
                CancellationToken = CancellationToken.None;
                _processedParentNodes.Clear();
                SemanticModel = null;
                HasMoreWork = false;
                alwaysSimplify = false;

                _pool.Free(this);
            }

            private static SyntaxNode GetParentNode(SyntaxNode node)
            {
                if (node is ExpressionSyntax expression)
                    return GetParentNode(expression);

                if (node is PatternSyntax pattern)
                    return GetParentNode(pattern);

                if (node is CrefSyntax cref)
                    return GetParentNode(cref);

                return null;
            }

            private static SyntaxNode GetParentNode(ExpressionSyntax expression)
            {
                var lastExpression = expression;
                for (SyntaxNode current = expression; current != null; current = current.Parent)
                {
                    if (current is ExpressionSyntax currentExpression)
                    {
                        lastExpression = currentExpression;
                    }
                }

                return lastExpression.Parent;
            }
<commit_msg>Use switch expression<commit_after>﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Simplification;

namespace Microsoft.CodeAnalysis.CSharp.Simplification
{
    internal abstract partial class AbstractCSharpReducer
    {
        protected abstract class AbstractReductionRewriter : CSharpSyntaxRewriter, IReductionRewriter
        {
            private readonly ObjectPool<IReductionRewriter> _pool;

            protected CSharpParseOptions ParseOptions { get; private set; }
            protected OptionSet OptionSet { get; private set; }
            protected CancellationToken CancellationToken { get; private set; }
            protected SemanticModel SemanticModel { get; private set; }

            public bool HasMoreWork { get; private set; }

            // can be used to simplify whole subtrees while just annotating one syntax node.
            // This is e.g. useful in the name simplification, where a whole qualified name is annotated
            protected bool alwaysSimplify;

            private readonly HashSet<SyntaxNode> _processedParentNodes = new HashSet<SyntaxNode>();

            protected AbstractReductionRewriter(ObjectPool<IReductionRewriter> pool)
                => _pool = pool;

            public void Initialize(ParseOptions parseOptions, OptionSet optionSet, CancellationToken cancellationToken)
            {
                ParseOptions = (CSharpParseOptions)parseOptions;
                OptionSet = optionSet;
                CancellationToken = cancellationToken;
            }

            public void Dispose()
            {
                ParseOptions = null;
                OptionSet = null;
                CancellationToken = CancellationToken.None;
                _processedParentNodes.Clear();
                SemanticModel = null;
                HasMoreWork = false;
                alwaysSimplify = false;

                _pool.Free(this);
            }

            private static SyntaxNode GetParentNode(SyntaxNode node)
                => node switch
                {
                    ExpressionSyntax expression => GetParentNode(expression),
                    PatternSyntax pattern => GetParentNode(pattern),
                    CrefSyntax cref => GetParentNode(cref),
                    _ => null
                };

            private static SyntaxNode GetParentNode(ExpressionSyntax expression)
            {
                var lastExpression = expression;
                for (SyntaxNode current = expression; current != null; current = current.Parent)
                {
                    if (current is ExpressionSyntax currentExpression)
                    {
                        lastExpression = currentExpression;
                    }
                }

                return lastExpression.Parent;
            }

{'fraction_non_alphanumeric': 0.05525709900230238, 'fraction_numerical': 0.0, 'mean_word_length': 1.9739844819717025, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1571766', 'n_tokens_mistral': 1472, 'n_tokens_neox': 1374, 'n_words': 441}