File: AddImport\SymbolResult.cs
Web Access
Project: src\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features)
// 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 Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.Shared.Extensions;
 
namespace Microsoft.CodeAnalysis.AddImport;
 
internal abstract partial class AbstractAddImportFeatureService<TSimpleNameSyntax>
{
    private readonly struct SearchResult(string? desiredName, TSimpleNameSyntax nameNode, IReadOnlyList<string> nameParts, double weight)
    {
        public readonly IReadOnlyList<string> NameParts = nameParts;
 
        // How good a match this was.  0 means it was a perfect match.  Larger numbers are less 
        // and less good.
        public readonly double Weight = weight;
 
        // The desired name to change the user text to if this was a fuzzy (spell-checking) match.
        public readonly string? DesiredName = desiredName;
 
        // The node to convert to the desired name
        public readonly TSimpleNameSyntax NameNode = nameNode;
 
        public SearchResult(SymbolResult<INamespaceOrTypeSymbol> result)
            : this(result.DesiredName, result.NameNode, INamespaceOrTypeSymbolExtensions.GetNameParts(result.Symbol), result.Weight)
        {
        }
 
        public bool DesiredNameDiffersFromSourceName()
        {
            return !string.IsNullOrEmpty(DesiredName) &&
                NameNode != null &&
                NameNode.GetFirstToken().ValueText != DesiredName;
        }
 
        public bool DesiredNameDiffersFromSourceNameOnlyByCase()
        {
            Debug.Assert(DesiredNameDiffersFromSourceName());
            return StringComparer.OrdinalIgnoreCase.Equals(
                NameNode.GetFirstToken().ValueText, DesiredName);
        }
 
        public bool DesiredNameMatchesSourceName(Document document)
        {
            if (!DesiredNameDiffersFromSourceName())
            {
                // Names match in any language.
                return true;
            }
 
            var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
 
            // Names differ.  But in a case insensitive language they may match.
            if (!syntaxFacts.IsCaseSensitive &&
                DesiredNameDiffersFromSourceNameOnlyByCase())
            {
                return true;
            }
 
            // Name are totally different in any language.
            return false;
        }
    }
 
    private readonly struct SymbolResult<T>(string desiredName, TSimpleNameSyntax nameNode, T symbol, double weight) where T : ISymbol
    {
        // The symbol that matched the string being searched for.
        public readonly T Symbol = symbol;
 
        // How good a match this was.  0 means it was a perfect match.  Larger numbers are less 
        // and less good.
        public readonly double Weight = weight;
 
        // The desired name to change the user text to if this was a fuzzy (spell-checking) match.
        public readonly string DesiredName = desiredName;
 
        // The node to convert to the desired name
        public readonly TSimpleNameSyntax NameNode = nameNode;
 
        public SymbolResult<T2> WithSymbol<T2>(T2 symbol) where T2 : ISymbol
            => new(DesiredName, NameNode, symbol, Weight);
 
        internal SymbolResult<T> WithDesiredName(string desiredName)
            => new(desiredName, NameNode, Symbol, Weight);
    }
 
    private struct SymbolResult
    {
        public static SymbolResult<T> Create<T>(string desiredName, TSimpleNameSyntax nameNode, T symbol, double weight) where T : ISymbol
            => new(desiredName, nameNode, symbol, weight);
    }
}