<commit_before>﻿namespace YC.ReSharper.AbstractAnalysis.LanguageApproximation.ConstantPropagation

open JetBrains.ReSharper.Psi.CSharp;
open JetBrains.ReSharper.Psi.CSharp.Tree;
open JetBrains.ReSharper.Psi.Tree;
open JetBrains.ReSharper.Psi;
open JetBrains.ReSharper.Psi.Files;
open AbstractLexer.Common
open Microsoft.FSharp.Collections

type Approximator(file:ICSharpFile) = 
    let count = ref 0
    let propagate (hotspot:IInvocationExpression) =
        let args = hotspot.ArgumentList.Arguments |> Array.ofSeq
        //|> Seq.map (fun arg -> arg.)
        let start = args.[0].Value
        let edges = new ResizeArray<_>()
        let rec go (node:ITreeNode) =
            match node with
            | :? IAdditiveExpression as a ->
                go a.LeftOperand 
                go a.RightOperand
            | :? ICSharpLiteralExpression as l -> 
                new LexerEdge<_,_>(!count,(incr count; !count),Some(l.Literal.GetText().Trim[|'"'|],l))
                |> edges.Add
            | _ -> ()

        go start
        let res = new LexerInputGraph<_>()
        res.AddVerticesAndEdgeRange edges |> ignore
        res.StartVertex <- 0
        res

        //ICshLiteralEx
        //referenceExpression
    member this.Approximate () =
        let hotspots = new ResizeArray<_>() 
        let addHotspot (node:ITreeNode) =
            match node with 
            | :? IInvocationExpression as m when m.InvocationExpressionReference.GetName().ToLowerInvariant() = "executeimmediate" -> hotspots.Add m
            | _ -> ()
        //InvocationExpressionNavigator.
        let processor = RecursiveElementProcessor(fun x -> addHotspot x)
        processor.Process file
        let graphs = ResizeArray.map propagate hotspots
        graphs


//        let hs4 = 
//            let processor = RecursiveElementProcessor(fun x -> addHotspot x)
//            processor.Process file
//        //let hs3 = file.
//        let hs2 = file.Children()// FindNodesAt(new TreeTextRange(file.GetTreeEndOffset()), fun x -> isHotspot x)
//        (hotspots |> Seq.map string |> String.concat "; ")
//        + (hs2 |> Seq.map string |> String.concat "; ")
//        + (hs3 |> Seq.map string |> String.concat "; ")
<commit_msg>Fix graph vertex count in approximator. Multiple hotspots are supported.<commit_after>﻿namespace YC.ReSharper.AbstractAnalysis.LanguageApproximation.ConstantPropagation

open JetBrains.ReSharper.Psi.CSharp;
open JetBrains.ReSharper.Psi.CSharp.Tree;
open JetBrains.ReSharper.Psi.Tree;
open JetBrains.ReSharper.Psi;
open JetBrains.ReSharper.Psi.Files;
open AbstractLexer.Common
open Microsoft.FSharp.Collections

type Approximator(file:ICSharpFile) = 
    let propagate (hotspot:IInvocationExpression) =
        let count = ref 0
        let args = hotspot.ArgumentList.Arguments |> Array.ofSeq
        //|> Seq.map (fun arg -> arg.)
        let start = args.[0].Value
        let edges = new ResizeArray<_>()
        let rec go (node:ITreeNode) =
            match node with
            | :? IAdditiveExpression as a ->
                go a.LeftOperand 
                go a.RightOperand
            | :? ICSharpLiteralExpression as l -> 
                new LexerEdge<_,_>(!count,(incr count; !count),Some(l.Literal.GetText().Trim[|'"'|],l))
                |> edges.Add
            | _ -> ()

        go start
        let res = new LexerInputGraph<_>()
        res.AddVerticesAndEdgeRange edges |> ignore
        res.StartVertex <- 0
        res

        //ICshLiteralEx
        //referenceExpression
    member this.Approximate () =
        let hotspots = new ResizeArray<_>() 
        let addHotspot (node:ITreeNode) =
            match node with 
            | :? IInvocationExpression as m when m.InvocationExpressionReference.GetName().ToLowerInvariant() = "executeimmediate" -> hotspots.Add m
            | _ -> ()
        //InvocationExpressionNavigator.
        let processor = RecursiveElementProcessor(fun x -> addHotspot x)
        processor.Process file
        let graphs = ResizeArray.map propagate hotspots
        graphs


//        let hs4 = 
//            let processor = RecursiveElementProcessor(fun x -> addHotspot x)
//            processor.Process file
//        //let hs3 = file.
//        let hs2 = file.Children()// FindNodesAt(new TreeTextRange(file.GetTreeEndOffset()), fun x -> isHotspot x)
//        (hotspots |> Seq.map string |> String.concat "; ")
//        + (hs2 |> Seq.map string |> String.concat "; ")
//        + (hs3 |> Seq.map string |> String.concat "; ")

{'fraction_non_alphanumeric': 0.11022604951560819, 'fraction_numerical': 0.003444564047362756, 'mean_word_length': 2.0686922060766184, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 49, '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': '254095', 'n_tokens_mistral': 1465, 'n_tokens_neox': 1357, 'n_words': 299}