<commit_before>﻿// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.NamingStyles;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers
{
    internal partial class DeclarationNameCompletionProvider
    {
        internal struct NameDeclarationInfo
        {
            public NameDeclarationInfo(
                ImmutableArray<SymbolKind> possibleSymbolKinds,
                Accessibility accessibility,
                DeclarationModifiers declarationModifiers,
                ITypeSymbol type,
                IAliasSymbol alias)
            {
                PossibleSymbolKinds = possibleSymbolKinds;
                DeclaredAccessibility = accessibility;
                Modifiers = declarationModifiers;
                Type = type;
                Alias = alias;
            }

            public ImmutableArray<SymbolKind> PossibleSymbolKinds { get; }
            public DeclarationModifiers Modifiers { get; }
            public ITypeSymbol Type { get; }
            public IAliasSymbol Alias { get; }
            public Accessibility DeclaredAccessibility { get; }

            internal static async Task<NameDeclarationInfo> GetDeclarationInfo(Document document, int position, CancellationToken cancellationToken)
            {
                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position);
                var semanticModel = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(token.SpanStart, 0), cancellationToken).ConfigureAwait(false);
                var typeInferenceService = document.GetLanguageService<ITypeInferenceService>();

                if (IsTupleElementDeclaration(token, semanticModel, position, cancellationToken, out var result)
                    || IsParameterDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsTypeParameterDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsVariableDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsIncompleteMemberDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsFieldDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsMethodDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsPropertyDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsPossibleOutVariableDeclaration(token, semanticModel, position, typeInferenceService, cancellationToken, out result)
                    || IsTupleExpressionDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsPossibleVariableOrLocalMethodDeclaration(token, semanticModel, position, cancellationToken, out result))
                {
                    return result;
                }

                return default;
            }

            private static bool IsTupleElementDeclaration(
                SyntaxToken token, SemanticModel semanticModel, int position,
                CancellationToken cancellationToken, out NameDeclarationInfo result)
            {
                result = IsFollowingTypeOrComma<TupleElementSyntax>(
                    token,
                    semanticModel,
                    tupleElement => tupleElement.Type,
                    _ => default(SyntaxTokenList),
                    _ => ImmutableArray.Create(SymbolKind.Local), cancellationToken);

                return result.Type != null;
            }

            private static bool IsTupleExpressionDeclaration(
                SyntaxToken token, SemanticModel semanticModel, int position,
                CancellationToken cancellationToken, out NameDeclarationInfo result)
            {
                if (token.GetAncestor(node => node.IsKind(SyntaxKind.TupleExpression)) != null)
                {
                    result = IsFollowingTypeOrComma<ArgumentSyntax>(
                        token,
                        semanticModel,
                        GetNodeDenotingTheTypeOfTupleArgument,
                        _ => default(SyntaxTokenList),
                        _ => ImmutableArray.Create(SymbolKind.Local), cancellationToken);
                    return result.Type != null;
                }

                result = default;<commit_msg>Renamed methods and added code comment.<commit_after>﻿// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.NamingStyles;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;

namespace Microsoft.CodeAnalysis.CSharp.Completion.Providers
{
    internal partial class DeclarationNameCompletionProvider
    {
        internal struct NameDeclarationInfo
        {
            public NameDeclarationInfo(
                ImmutableArray<SymbolKind> possibleSymbolKinds,
                Accessibility accessibility,
                DeclarationModifiers declarationModifiers,
                ITypeSymbol type,
                IAliasSymbol alias)
            {
                PossibleSymbolKinds = possibleSymbolKinds;
                DeclaredAccessibility = accessibility;
                Modifiers = declarationModifiers;
                Type = type;
                Alias = alias;
            }

            public ImmutableArray<SymbolKind> PossibleSymbolKinds { get; }
            public DeclarationModifiers Modifiers { get; }
            public ITypeSymbol Type { get; }
            public IAliasSymbol Alias { get; }
            public Accessibility DeclaredAccessibility { get; }

            internal static async Task<NameDeclarationInfo> GetDeclarationInfo(Document document, int position, CancellationToken cancellationToken)
            {
                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var token = tree.FindTokenOnLeftOfPosition(position, cancellationToken).GetPreviousTokenIfTouchingWord(position);
                var semanticModel = await document.GetSemanticModelForSpanAsync(new Text.TextSpan(token.SpanStart, 0), cancellationToken).ConfigureAwait(false);
                var typeInferenceService = document.GetLanguageService<ITypeInferenceService>();

                if (IsTupleTypeElement(token, semanticModel, position, cancellationToken, out var result)
                    || IsParameterDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsTypeParameterDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsVariableDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsIncompleteMemberDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsFieldDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsMethodDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsPropertyDeclaration(token, semanticModel, position, cancellationToken, out result)
                    || IsPossibleOutVariableDeclaration(token, semanticModel, position, typeInferenceService, cancellationToken, out result)
                    || IsTupleLiteralElement(token, semanticModel, position, cancellationToken, out result)
                    || IsPossibleVariableOrLocalMethodDeclaration(token, semanticModel, position, cancellationToken, out result))
                {
                    return result;
                }

                return default;
            }

            private static bool IsTupleTypeElement(
                SyntaxToken token, SemanticModel semanticModel, int position,
                CancellationToken cancellationToken, out NameDeclarationInfo result)
            {
                result = IsFollowingTypeOrComma<TupleElementSyntax>(
                    token,
                    semanticModel,
                    tupleElement => tupleElement.Type,
                    _ => default(SyntaxTokenList),
                    _ => ImmutableArray.Create(SymbolKind.Local), cancellationToken);

                return result.Type != null;
            }

            private static bool IsTupleLiteralElement(
                SyntaxToken token, SemanticModel semanticModel, int position,
                CancellationToken cancellationToken, out NameDeclarationInfo result)
            {
                // Incomplete code like
                // void Do()
                // {
                //    (System.Array array, System.Action $$ 
                // gets parsed as a tuple expression. We can figure out the type in such cases.
                // For a legit tuple expression we can't provide any completion.
                if (token.GetAncestor(node => node.IsKind(SyntaxKind.TupleExpression)) != null)
                {
                    result = IsFollowingTypeOrComma<ArgumentSyntax>(
                        token,
                        semanticModel,
                        GetNodeDenotingTheTypeOfTupleArgument,
                        _ => default(SyntaxTokenList),
                        _ => ImmutableArray.Create(SymbolKind.Local), cancellationToken);
                    return result.Type != null;
                }

                result = default;
{'fraction_non_alphanumeric': 0.0635039223010833, 'fraction_numerical': 0.0005603287261860292, 'mean_word_length': 2.304227090404196, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 27, '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': '5665829', 'n_tokens_mistral': 2376, 'n_tokens_neox': 2219, 'n_words': 561}