<commit_before>﻿using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace DebuggerShared.Visualizer.QueryComprehension
{
    public class QueryComprehensionToFluentRewriter : CSharpSyntaxRewriter
    {
        private class QueryState
        {
            public SyntaxToken AnonymousTypeIdentifier { get; } = Identifier("@t");
            public Dictionary<string, int> IdentifiersChain { get; } = new Dictionary<string, int>();
            public ExpressionSyntax FluentExpression { get; set; }
            public SyntaxToken SourceIdentifier { get; set; }
            public bool IsAnonymousType { get; set; }
        }

        private readonly SemanticModel _model;
        private readonly QueryState _state;

        public QueryComprehensionToFluentRewriter(SemanticModel model)
        {
            _model = model;
            _state = new QueryState();
        }

        #region Visitors

        public override SyntaxNode VisitQueryExpression(QueryExpressionSyntax node)
        {
            _state.FluentExpression = (ExpressionSyntax)VisitFromClause(node.FromClause);
            VisitQueryBody(node.Body);
            var fluentQuery = ConcatInvocations();
             return _state.FluentExpression;
        }

        public override SyntaxNode VisitQueryBody(QueryBodySyntax node)
        {
            foreach(QueryClauseSyntax clause in node.Clauses)
            {
                var fromClauseSyntax = clause as FromClauseSyntax;
                InvocationExpressionSyntax fluentInvocation =
                    fromClauseSyntax != null
                    ? CreateSelectMany(fromClauseSyntax)
                    : (InvocationExpressionSyntax)Visit(clause);

                _state.FluentExpression = InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        _state.FluentExpression,
                        (IdentifierNameSyntax)fluentInvocation.Expression),
                    fluentInvocation.ArgumentList);
            }

            var selectOrGroup = (InvocationExpressionSyntax)Visit(node.SelectOrGroup);
            _state.FluentExpression = InvocationExpression(
                   MemberAccessExpression(
                       SyntaxKind.SimpleMemberAccessExpression,
                       _state.FluentExpression,
                       (IdentifierNameSyntax)selectOrGroup.Expression),
                   selectOrGroup.ArgumentList);

            if(node.Continuation != null)
            {
                VisitQueryContinuation(node.Continuation);
            }
            return node;
        }

        public override SyntaxNode VisitQueryContinuation(QueryContinuationSyntax node)
        {
            _state.IsAnonymousType = false;
            _state.IdentifiersChain.Clear();
            _state.SourceIdentifier = node.Identifier;
            _state.IdentifiersChain[_state.SourceIdentifier.ValueText] = 0;
            VisitQueryBody(node.Body);
            return node;
        }

        public override SyntaxNode VisitFromClause(FromClauseSyntax node)
        {
            _state.SourceIdentifier = node.Identifier;
            _state.IdentifiersChain[_state.SourceIdentifier.ValueText] = 0;

            if(node.Type == null)
            {
                return node.Expression;
            }

            return InvocationExpression(
                     MemberAccessExpression(
                         SyntaxKind.SimpleMemberAccessExpression,
                         node.Expression,
                         IdentifierName($"Cast<{node.Type}>")));
        }

        public override SyntaxNode VisitWhereClause(WhereClauseSyntax node)
        {
            var condition = (ExpressionSyntax)Visit(node.Condition);
            return BuildFluentInvocation("Where", BuildSimpleLambdaExpression(condition));
        }<commit_msg>Don't visit inner where arguments<commit_after>﻿using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;

namespace DebuggerShared.Visualizer.QueryComprehension
{
    public class QueryComprehensionToFluentRewriter : CSharpSyntaxRewriter
    {
        private class QueryState
        {
            public SyntaxToken AnonymousTypeIdentifier { get; } = Identifier("@t");
            public Dictionary<string, int> IdentifiersChain { get; } = new Dictionary<string, int>();
            public ExpressionSyntax FluentExpression { get; set; }
            public SyntaxToken SourceIdentifier { get; set; }
            public bool IsAnonymousType { get; set; }
        }

        private readonly SemanticModel _model;
        private readonly QueryState _state;

        public QueryComprehensionToFluentRewriter(SemanticModel model)
        {
            _model = model;
            _state = new QueryState();
        }

        #region Visitors

        public override SyntaxNode VisitQueryExpression(QueryExpressionSyntax node)
        {
            _state.FluentExpression = (ExpressionSyntax)VisitFromClause(node.FromClause);
            VisitQueryBody(node.Body);
            var fluentQuery = ConcatInvocations();
             return _state.FluentExpression;
        }

        public override SyntaxNode VisitQueryBody(QueryBodySyntax node)
        {
            foreach(QueryClauseSyntax clause in node.Clauses)
            {
                var fromClauseSyntax = clause as FromClauseSyntax;
                InvocationExpressionSyntax fluentInvocation =
                    fromClauseSyntax != null
                    ? CreateSelectMany(fromClauseSyntax)
                    : (InvocationExpressionSyntax)Visit(clause);

                _state.FluentExpression = InvocationExpression(
                    MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        _state.FluentExpression,
                        (IdentifierNameSyntax)fluentInvocation.Expression),
                    fluentInvocation.ArgumentList);
            }

            var selectOrGroup = (InvocationExpressionSyntax)Visit(node.SelectOrGroup);
            _state.FluentExpression = InvocationExpression(
                   MemberAccessExpression(
                       SyntaxKind.SimpleMemberAccessExpression,
                       _state.FluentExpression,
                       (IdentifierNameSyntax)selectOrGroup.Expression),
                   selectOrGroup.ArgumentList);

            if(node.Continuation != null)
            {
                VisitQueryContinuation(node.Continuation);
            }
            return node;
        }

        public override SyntaxNode VisitQueryContinuation(QueryContinuationSyntax node)
        {
            _state.IsAnonymousType = false;
            _state.IdentifiersChain.Clear();
            _state.SourceIdentifier = node.Identifier;
            _state.IdentifiersChain[_state.SourceIdentifier.ValueText] = 0;
            VisitQueryBody(node.Body);
            return node;
        }

        public override SyntaxNode VisitFromClause(FromClauseSyntax node)
        {
            _state.SourceIdentifier = node.Identifier;
            _state.IdentifiersChain[_state.SourceIdentifier.ValueText] = 0;

            if(node.Type == null)
            {
                return node.Expression;
            }

            return InvocationExpression(
                     MemberAccessExpression(
                         SyntaxKind.SimpleMemberAccessExpression,
                         node.Expression,
                         IdentifierName($"Cast<{node.Type}>")));
        }

        public override SyntaxNode VisitWhereClause(WhereClauseSyntax node)
        {
            return BuildFluentInvocation("Where", BuildSimpleLambdaExpression(node.Condition));
        }
{'fraction_non_alphanumeric': 0.0644723865877712, 'fraction_numerical': 0.0004930966469428008, 'mean_word_length': 2.008157211716722, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, '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': '5447947', 'n_tokens_mistral': 1887, 'n_tokens_neox': 1797, 'n_words': 341}