<commit_before>﻿#region Using Directives

using System;
using System.Collections.Immutable;
using System.Threading.Tasks;

using JetBrains.Annotations;

using Pharmatechnik.Nav.Language.Text;

#endregion

namespace Pharmatechnik.Nav.Language.FindReferences {

    public class ReferenceFinder {

        public static Task FindReferences(FindReferencesArgs args) {

            if (args == null) {
                throw new ArgumentNullException(nameof(args));
            }

            return Task.Run(async () => {

                var definition = FindDefinitionVisitor.Invoke(args.Symbol);
                if (definition == null) {
                    return;
                }

                var searchRoot     = args.SearchDirectory?.FullName ?? definition.SyntaxTree?.SourceText.FileInfo?.FullName ?? "";
                var definitionItem = new DefinitionItem(searchRoot, definition, definition.ToDisplayParts());

                foreach (var reference in FindReferencesVisitor.Invoke(args, definitionItem)
                    //.OrderBy(d => d.Location.StartLine)
                    //.ThenBy(d => d.Location.StartCharacter)
                ) {

                    if (args.Context.CancellationToken.IsCancellationRequested) {
                        return;
                    }

                    var referenceItem = ToReferenceItem(definitionItem, reference);

                    if (referenceItem == null) {
                        continue;
                    }

                    await args.Context.OnReferenceFoundAsync(referenceItem);

                }

            });

        }

        [CanBeNull]
        static ReferenceItem ToReferenceItem(DefinitionItem definitionItem, ISymbol reference) {

            if (definitionItem == null || reference.SyntaxTree == null) {
                return null;
            }

            var referenceLine = reference.SyntaxTree.SourceText.GetTextLineAtPosition(reference.Location.Start);

            // Text
            var textExtent = referenceLine.ExtentWithoutLineEndings;

            var prefix               = "";
            var prefixClassification = TextClassification.Text;
            if (reference is INodeSymbol node) {
                prefix               = $"{node.ContainingTask.Name} \u220B";
                prefixClassification = TextClassification.TaskName;
            }

            if (reference is INodeReferenceSymbol nodeReference && nodeReference.Declaration is INodeSymbol nodeSymbol) {
                prefix               = $"{nodeSymbol.ContainingTask.Name} \u220B";
                prefixClassification = TextClassification.TaskName;
            }

            var textParts = reference.SyntaxTree
                                     .GetClassifiedText(textExtent)
                                     .ToImmutableArray();

            if (!String.IsNullOrEmpty(prefix)) {
                textParts = textParts.Insert(0, new ClassifiedText(prefix, prefixClassification));

            }

            var textHighlightExtent = new TextExtent(start: reference.Start - referenceLine.Start + prefix.Length,
                                                     length: reference.Location.Length);

            // Preview
            var previewExtent = GetPreviewExtent(referenceLine);<commit_msg>UI Experimente<commit_after>﻿#region Using Directives

using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading.Tasks;

using JetBrains.Annotations;

using Pharmatechnik.Nav.Language.Text;

#endregion

namespace Pharmatechnik.Nav.Language.FindReferences {

    public class ReferenceFinder {

        public static Task FindReferences(FindReferencesArgs args) {

            if (args == null) {
                throw new ArgumentNullException(nameof(args));
            }

            return Task.Run(async () => {

                var definition = FindDefinitionVisitor.Invoke(args.Symbol);
                if (definition == null) {
                    return;
                }

                var searchRoot     = args.SearchDirectory?.FullName ?? definition.SyntaxTree?.SourceText.FileInfo?.FullName ?? "";
                var definitionItem = new DefinitionItem(searchRoot, definition, definition.ToDisplayParts());

                foreach (var reference in FindReferencesVisitor.Invoke(args, definitionItem)
                    //.OrderBy(d => d.Location.StartLine)
                    //.ThenBy(d => d.Location.StartCharacter)
                ) {

                    if (args.Context.CancellationToken.IsCancellationRequested) {
                        return;
                    }

                    var referenceItem = ToReferenceItem(definitionItem, reference);

                    if (referenceItem == null) {
                        continue;
                    }

                    await args.Context.OnReferenceFoundAsync(referenceItem);

                }

            });

        }

        [CanBeNull]
        static ReferenceItem ToReferenceItem(DefinitionItem definitionItem, ISymbol reference) {

            if (definitionItem == null || reference.SyntaxTree == null) {
                return null;
            }

            var referenceLine = reference.SyntaxTree.SourceText.GetTextLineAtPosition(reference.Location.Start);

            // Text
            var textExtent = referenceLine.ExtentWithoutLineEndings;

            var prefixParts          = ImmutableArray<ClassifiedText>.Empty;

            if (reference is INodeSymbol node) {

                prefixParts = new[] {
                    new ClassifiedText($"{node.ContainingTask.Name}", TextClassification.TaskName),
                    new ClassifiedText(" \u220B",                     TextClassification.Text)

                }.ToImmutableArray();
            }

            if (reference is INodeReferenceSymbol nodeReference && nodeReference.Declaration is INodeSymbol nodeSymbol) {
                prefixParts = new[] {
                    new ClassifiedText($"{nodeSymbol.ContainingTask.Name}", TextClassification.TaskName),
                    new ClassifiedText(" \u220B",                           TextClassification.Text)

                }.ToImmutableArray();
            }

            var textParts = reference.SyntaxTree
                                     .GetClassifiedText(textExtent)
                                     .ToImmutableArray();

            if (prefixParts.Any()) {
                textParts = prefixParts.AddRange(textParts);

            }

            var textHighlightExtent = new TextExtent(start: reference.Start - referenceLine.Start + prefixParts.JoinText().Length,
                                                     length: reference.Location.Length);

            // Preview
            var previewExtent = GetPreviewExtent(referenceLine);
{'fraction_non_alphanumeric': 0.08064516129032258, 'fraction_numerical': 0.001906158357771261, 'mean_word_length': 1.6561526479750779, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7140878', 'n_tokens_mistral': 1613, 'n_tokens_neox': 1486, 'n_words': 301}