<commit_before>﻿namespace MonoDevelop.FSharp
open System
open System.Collections.Generic
open System.Reflection
open Microsoft.FSharp.Compiler.SourceCodeServices
open Mono.TextEditor
open MonoDevelop
open MonoDevelop.Ide
open MonoDevelop.Components

module Symbols =
    ///Given a column and line string returns the identifier portion of the string
    let lastIdent column lineString =
        match FSharp.CompilerBinding.Parsing.findLongIdents(column, lineString) with
        | Some (_col, identIsland) -> Seq.last identIsland
        | None -> ""

    ///Returns a TextSegment that is trimmed to only include the identifier
    let getTextSegment (doc:Editor.TextEditor) (symbolUse:FSharpSymbolUse) column line =
        let lastIdent = lastIdent column line
        let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent

        let startOffset = doc.LocationToOffset(start.Line, start.Column+1)
        let endOffset = doc.LocationToOffset(finish.Line, finish.Column+1)
        MonoDevelop.Core.Text.TextSegment.FromBounds(startOffset, endOffset)

    let getEditorForFileName (fileName:string) =
        match IdeApp.Workbench.GetDocument (fileName) with
        | null ->           
            let doc = MonoDevelop.Ide.Editor.TextEditorFactory.LoadDocument (fileName)
            MonoDevelop.Ide.Editor.TextEditorFactory.CreateNewEditor (doc)
        | doc -> doc.Editor

    let getTrimmedRangesForDeclarations lastIdent (symbolUse:FSharpSymbolUse) =
        symbolUse
        |> Roslyn.getSymbolLocations
        |> List.map (fun range -> 
            let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent
            range.FileName, start, finish)

    let getTextSpanForDeclarations lastIdent (symbolUse:FSharpSymbolUse) =
        let trimmedSymbols = getTrimmedRangesForDeclarations lastIdent symbolUse
        trimmedSymbols
        |> List.map (fun (fileName, start, finish) ->
            let editor = getEditorForFileName fileName
            let startOffset = editor.LocationToOffset (start.Line, start.Column+1)
            let endOffset = editor.LocationToOffset (finish.Line, finish.Column+1)
            let ts = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds (startOffset, endOffset)
            let ls = Microsoft.CodeAnalysis.Text.LinePositionSpan(Microsoft.CodeAnalysis.Text.LinePosition(start.Line, start.Column),
                                                                  Microsoft.CodeAnalysis.Text.LinePosition(finish.Line, finish.Column))
            fileName, ts, ls)

    let getTextSpan lastIdent (symbolUse:FSharpSymbolUse) =
        let range = symbolUse.RangeAlternate
        let editor = getEditorForFileName symbolUse.RangeAlternate.FileName

        let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent

        let startOffset = editor.LocationToOffset (start.Line, start.Column+1)
        let endOffset = editor.LocationToOffset (finish.Line, finish.Column+1)
        range.FileName, Microsoft.CodeAnalysis.Text.TextSpan.FromBounds (startOffset, endOffset)

[<AutoOpen>]
module FSharpTypeExt =
    let isOperatorOrActivePattern (name: string) =
            if name.StartsWith "( " && name.EndsWith " )" && name.Length > 4 then
                name.Substring (2, name.Length - 4) |> String.forall (fun c -> c <> ' ')
            else false

    let isConstructor (func: FSharpMemberOrFunctionOrValue) =
        func.CompiledName = ".ctor"

[<AutoOpen>]
module CorePatterns =
    let (|ActivePatternCase|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpActivePatternCase as ap-> ActivePatternCase(ap) |> Some
        | _ -> None

    let (|Entity|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpEntity as ent -> Some ent
        | _ -> None

    let (|Field|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpField as field-> Some field
        |  _ -> None

    let (|GenericParameter|_|) (symbol: FSharpSymbolUse) = <commit_msg>Added getTextSpan function using supplied readonly editor<commit_after>﻿namespace MonoDevelop.FSharp
open System
open System.Collections.Generic
open System.Reflection
open Microsoft.FSharp.Compiler.SourceCodeServices
open Mono.TextEditor
open MonoDevelop
open MonoDevelop.Ide
open MonoDevelop.Components

module Symbols =
    ///Given a column and line string returns the identifier portion of the string
    let lastIdent column lineString =
        match FSharp.CompilerBinding.Parsing.findLongIdents(column, lineString) with
        | Some (_col, identIsland) -> Seq.last identIsland
        | None -> ""

    ///Returns a TextSegment that is trimmed to only include the identifier
    let getTextSegment (doc:Editor.TextEditor) (symbolUse:FSharpSymbolUse) column line =
        let lastIdent = lastIdent column line
        let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent

        let startOffset = doc.LocationToOffset(start.Line, start.Column+1)
        let endOffset = doc.LocationToOffset(finish.Line, finish.Column+1)
        MonoDevelop.Core.Text.TextSegment.FromBounds(startOffset, endOffset)

    let getEditorForFileName (fileName:string) =
        match IdeApp.Workbench.GetDocument (fileName) with
        | null ->           
            let doc = MonoDevelop.Ide.Editor.TextEditorFactory.LoadDocument (fileName)
            MonoDevelop.Ide.Editor.TextEditorFactory.CreateNewEditor (doc)
        | doc -> doc.Editor

    let getTrimmedRangesForDeclarations lastIdent (symbolUse:FSharpSymbolUse) =
        symbolUse
        |> Roslyn.getSymbolLocations
        |> List.map (fun range -> 
            let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent
            range.FileName, start, finish)

    let getTextSpanForDeclarations lastIdent (symbolUse:FSharpSymbolUse) =
        let trimmedSymbols = getTrimmedRangesForDeclarations lastIdent symbolUse
        trimmedSymbols
        |> List.map (fun (fileName, start, finish) ->
            let editor = getEditorForFileName fileName
            let startOffset = editor.LocationToOffset (start.Line, start.Column+1)
            let endOffset = editor.LocationToOffset (finish.Line, finish.Column+1)
            let ts = Microsoft.CodeAnalysis.Text.TextSpan.FromBounds (startOffset, endOffset)
            let ls = Microsoft.CodeAnalysis.Text.LinePositionSpan(Microsoft.CodeAnalysis.Text.LinePosition(start.Line, start.Column),
                                                                  Microsoft.CodeAnalysis.Text.LinePosition(finish.Line, finish.Column))
            fileName, ts, ls)

    let getTextSpanTrimmed lastIdent (symbolUse:FSharpSymbolUse) =
        let range = symbolUse.RangeAlternate
        let editor = getEditorForFileName symbolUse.RangeAlternate.FileName

        let start, finish = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent

        let startOffset = editor.LocationToOffset (start.Line, start.Column+1)
        let endOffset = editor.LocationToOffset (finish.Line, finish.Column+1)
        range.FileName, Microsoft.CodeAnalysis.Text.TextSpan.FromBounds (startOffset, endOffset)

    let getTextSpan (range:Microsoft.FSharp.Compiler.Range.range) (editor:Editor.IReadonlyTextDocument) =
        let startOffset = editor.LocationToOffset (range.StartLine, range.StartColumn+1)
        let endOffset = editor.LocationToOffset (range.EndLine, range.EndColumn+1)
        Microsoft.CodeAnalysis.Text.TextSpan.FromBounds (startOffset, endOffset)

[<AutoOpen>]
module FSharpTypeExt =
    let isOperatorOrActivePattern (name: string) =
            if name.StartsWith "( " && name.EndsWith " )" && name.Length > 4 then
                name.Substring (2, name.Length - 4) |> String.forall (fun c -> c <> ' ')
            else false

    let isConstructor (func: FSharpMemberOrFunctionOrValue) =
        func.CompiledName = ".ctor"

[<AutoOpen>]
module CorePatterns =
    let (|ActivePatternCase|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpActivePatternCase as ap-> ActivePatternCase(ap) |> Some
        | _ -> None

    let (|Entity|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpEntity as ent -> Some ent
        | _ -> None

    let (|Field|_|) (symbol : FSharpSymbolUse) =
        match symbol.Symbol with
        | :? FSharpField as field-> Some field
        |  _ -> None

    let (|GenericParameter|_|) (symbol: FSharpSymbolUse) = 
{'fraction_non_alphanumeric': 0.08619285797371176, 'fraction_numerical': 0.0023263929277654995, 'mean_word_length': 3.0009306654257792, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6343772', 'n_tokens_mistral': 2402, 'n_tokens_neox': 2278, 'n_words': 559}