Пример #1
0
        private static AutocompletionContextResult FindAutocompletionContext(IConsoleInput consoleInput)
        {
            var result = new AutocompletionContextResult {
                StartIndex = 0
            };

            for (int i = Math.Min(consoleInput.CaretIndex, consoleInput.Length - 1); i >= 0; i--)
            {
                if (consoleInput[i] == FunctionEndSymbol)
                {
                    result.Context = AutocompletionContext.Regular;
                    break;
                }
                if (consoleInput[i] == FunctionStartSymbol)
                {
                    result.Context    = AutocompletionContext.Method;
                    result.StartIndex = i + 1;
                    break;
                }
            }
            return(result);
        }
Пример #2
0
        public void Autocomplete(IConsoleInput consoleInput, bool isNextValue)
        {
            // Which context we in, method or regular.
            AutocompletionContextResult contextResult = FindAutocompletionContext(consoleInput);
            Type typeToPrefer = null;

            if (contextResult.Context == AutocompletionContext.Method)
            {
                long newCommandLength_whichParamAt_newStartIndex_numParams = FindParamIndexNewStartIndexAndNumParams(consoleInput, contextResult.StartIndex);
                int  chainEndIndex = FindPreviousLinkEndIndex(consoleInput, contextResult.StartIndex - 1);
                if (chainEndIndex >= 0)
                {
                    Stack <string> accessorChain = FindAccessorChain(consoleInput, chainEndIndex);
                    Member         lastChainLink = FindLastChainLinkMember(accessorChain);
                    if (lastChainLink?.ParameterInfo != null)
                    {
                        var             numParams = (int)(newCommandLength_whichParamAt_newStartIndex_numParams & 0xff);
                        ParameterInfo[] overload  = null;
                        for (int i = numParams; i <= lastChainLink.ParameterInfo.Max(x => x.Length); i++)
                        {
                            ParameterInfo[] overloadCandidate = lastChainLink.ParameterInfo.FirstOrDefault(x => x.Length == i);
                            if (overloadCandidate != null)
                            {
                                overload = overloadCandidate;
                                break;
                            }
                        }
                        if (overload != null)
                        {
                            var paramIndex = newCommandLength_whichParamAt_newStartIndex_numParams >> 32 & 0xff;
                            if (overload.Length > paramIndex)
                            {
                                typeToPrefer = overload[paramIndex].ParameterType;
                            }
                        }
                    }
                }
            }

            int                autocompleteBoundaryIndices = FindBoundaryIndices(consoleInput, consoleInput.CaretIndex);
            int                startIndex     = autocompleteBoundaryIndices & 0xff;
            int                length         = autocompleteBoundaryIndices >> 16;
            string             command        = consoleInput.Substring(startIndex, length);
            AutocompletionType completionType = FindAutocompleteType(consoleInput, startIndex);

            if (completionType == AutocompletionType.Regular)
            {
                if (typeToPrefer == null || !string.IsNullOrWhiteSpace(command))
                {
                    FindAutocompleteForEntries(consoleInput, InstancesAndStatics, command, startIndex, isNextValue);
                }
                else
                {
                    FindAutocompleteForEntries(consoleInput, GetAvailableNamesForType(typeToPrefer), command, startIndex, isNextValue);
                }
            }
            else // Accessor or assignment or method.
            {
                // We also need to find the value for whatever was before the type accessor.
                int chainEndIndex = FindPreviousLinkEndIndex(consoleInput, startIndex - 1);
                if (chainEndIndex < 0)
                {
                    return;
                }

                Stack <string> accessorChain = FindAccessorChain(consoleInput, chainEndIndex);
                Member         lastChainLink = FindLastChainLinkMember(accessorChain);
                // If no types were found, that means we are assigning a new variable.
                // Provide all autocomplete entries in that scenario.
                if (lastChainLink == null)
                {
                    FindAutocompleteForEntries(consoleInput, InstancesAndStatics, command, startIndex, isNextValue);
                    return;
                }

                switch (completionType)
                {
                case AutocompletionType.Accessor:
                    MemberCollection autocompleteValues;
                    if (lastChainLink.IsInstance)
                    {
                        _interpreter.InstanceMembers.TryGetValue(lastChainLink.Type, out autocompleteValues);
                    }
                    else
                    {
                        _interpreter.StaticMembers.TryGetValue(lastChainLink.Type, out autocompleteValues);
                    }
                    if (autocompleteValues == null)
                    {
                        break;
                    }
                    FindAutocompleteForEntries(consoleInput, autocompleteValues.Names, command, startIndex, isNextValue);
                    break;

                case AutocompletionType.Assignment:
                    FindAutocompleteForEntries(
                        consoleInput,
                        GetAvailableNamesForType(lastChainLink.Type),
                        command,
                        startIndex,
                        isNextValue);
                    break;
                }
            }
        }