Ejemplo n.º 1
0
        /// <summary>
        /// Adds suggestions for type scoped at current cursor position.
        /// </summary>
        public static void AddTopLevelSuggestionsForCursorType(IntellisenseData.IntellisenseData intellisenseData, CallNode callNode, int argPosition)
        {
            Contracts.AssertValue(intellisenseData);
            Contracts.AssertValue(callNode);
            Contracts.Assert(argPosition >= 0);

            CallInfo info = intellisenseData.Binding.GetInfo(callNode);

            Contracts.AssertValue(info);
            DType type = info.CursorType;

            // Suggestions are added for the error nodes in the next step.
            if (info.Function != null &&
                argPosition <= info.Function.MaxArity &&
                info.Function.IsLambdaParam(argPosition) &&
                !info.Function.HasSuggestionsForParam(argPosition) &&
                type.IsValid)
            {
                if (info.Function.IsLambdaParam(argPosition) && type.ContainsDataEntityType(DPath.Root))
                {
                    bool error = false;
                    type = type.DropAllOfTableRelationships(ref error, DPath.Root);
                    if (error)
                    {
                        return;
                    }
                }

                if (info.ScopeIdentifier != default)
                {
                    AddSuggestion(intellisenseData, info.ScopeIdentifier, SuggestionKind.Global, SuggestionIconKind.Other, type, requiresSuggestionEscaping: false);
                }

                if (!info.RequiresScopeIdentifier)
                {
                    AddTopLevelSuggestions(intellisenseData, type);
                }
            }
        }
Ejemplo n.º 2
0
            /// <summary>
            /// Adds suggestions as appropriate to the internal Suggestions and SubstringSuggestions lists of intellisenseData.
            /// Returns true if intellisenseData is handled and no more suggestions are to be found and false otherwise.
            /// </summary>
            public bool Run(IntellisenseData.IntellisenseData intellisenseData)
            {
                Contracts.AssertValue(intellisenseData);

                if (!TryGetRecordNodeWithinACallNode(intellisenseData.CurNode, out RecordNode recordNode, out CallNode callNode))
                {
                    return(false);
                }

                // For the special case of an identifier of a record which is an argument of a function, we can
                // utilize the data provided to suggest relevant column names
                int cursorPos = intellisenseData.CursorPos;

                bool suggestionsAdded = false;

                Contracts.AssertValue(recordNode);
                Contracts.AssertValue(callNode);

                Identifier columnName = GetRecordIdentifierForCursorPosition(cursorPos, recordNode, intellisenseData.Script);

                if (columnName == null)
                {
                    return(false);
                }

                if (columnName.Token.Span.Min <= cursorPos)
                {
                    var tokenSpan         = columnName.Token.Span;
                    int replacementLength = tokenSpan.Min == cursorPos ? 0 : tokenSpan.Lim - tokenSpan.Min;
                    intellisenseData.SetMatchArea(tokenSpan.Min, cursorPos, replacementLength);
                }

                CallInfo info = intellisenseData.Binding.GetInfo(callNode);
                var      func = info.Function;

                if (func == null || !intellisenseData.IsFunctionElligibleForRecordSuggestions(func))
                {
                    return(false);
                }

                // Adding suggestions for callNode arguments which reference a collection's columns
                if (func.CanSuggestInputColumns)
                {
                    DType aggregateType = GetAggregateType(func, callNode, intellisenseData);
                    if (aggregateType.HasErrors || !aggregateType.IsAggregate)
                    {
                        return(false);
                    }

                    if (aggregateType.ContainsDataEntityType(DPath.Root))
                    {
                        bool error = false;
                        aggregateType = aggregateType.DropAllOfTableRelationships(ref error, DPath.Root);
                        if (error)
                        {
                            return(false);
                        }
                    }

                    foreach (TypedName tName in aggregateType.GetNames(DPath.Root))
                    {
                        var    usedName = tName.Name;
                        string maybeDisplayName;
                        if (DType.TryGetDisplayNameForColumn(aggregateType, usedName, out maybeDisplayName))
                        {
                            usedName = new DName(maybeDisplayName);
                        }

                        string suggestion = TexlLexer.EscapeName(usedName.Value) + (IntellisenseHelper.IsPunctuatorColonNextToCursor(cursorPos, intellisenseData.Script) ? "" : TexlLexer.PunctuatorColon);
                        suggestionsAdded |= IntellisenseHelper.AddSuggestion(intellisenseData, suggestion, SuggestionKind.Field, SuggestionIconKind.Other, DType.String, requiresSuggestionEscaping: false);
                    }

                    return(suggestionsAdded && columnName != null);
                }

                return(intellisenseData.TryAddFunctionRecordSuggestions(func, callNode, columnName));
            }