Beispiel #1
0
        internal static IEnumerable <KeyValuePair <string, DType> > GetSuggestionsFromType(DType typeToSuggestFrom, DType suggestionType)
        {
            Contracts.AssertValid(typeToSuggestFrom);
            Contracts.AssertValid(suggestionType);

            // If no suggestion type provided, accept all suggestions.
            if (suggestionType == DType.Invalid)
            {
                suggestionType = DType.Error;
            }

            List <KeyValuePair <string, DType> > suggestions = new List <KeyValuePair <string, DType> >();

            foreach (TypedName tName in typeToSuggestFrom.GetNames(DPath.Root))
            {
                if (suggestionType.Accepts(tName.Type))
                {
                    var    usedName = tName.Name.Value;
                    string maybeDisplayName;
                    if (DType.TryGetDisplayNameForColumn(typeToSuggestFrom, usedName, out maybeDisplayName))
                    {
                        usedName = maybeDisplayName;
                    }

                    suggestions.Add(new KeyValuePair <string, DType>(usedName, tName.Type));
                }
            }
            return(suggestions);
        }
Beispiel #2
0
        public override bool CheckInvocation(TexlBinding binding, TexlNode[] args, DType[] argTypes, IErrorContainer errors, out DType returnType, out Dictionary <TexlNode, DType> nodeToCoercedTypeMap)
        {
            Contracts.AssertValue(args);
            Contracts.AssertAllValues(args);
            Contracts.AssertValue(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.AssertValue(errors);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

            bool fValid = base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);

            // The argument should be a table of one column.
            DType argType = argTypes[0];

            if (!argType.IsTable)
            {
                fValid = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrNeedTable_Func, Name);
            }
            else if (argType.GetNames(DPath.Root).Count() != 1)
            {
                fValid = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrNeedTableCol_Func, Name);
            }

            return(fValid);
        }
Beispiel #3
0
        internal static IEnumerable <KeyValuePair <string, DType> > GetColumnNameStringSuggestions(DType scopeType)
        {
            Contracts.AssertValid(scopeType);

            foreach (var name in scopeType.GetNames(DPath.Root))
            {
                yield return(new KeyValuePair <string, DType>(("\"" + CharacterUtils.ExcelEscapeString(name.Name.Value) + "\""), name.Type));
            }
        }
            private static void AddSuggestionsForScopeFields(IntellisenseData.IntellisenseData intellisenseData, DType scope)
            {
                Contracts.AssertValue(intellisenseData);
                Contracts.Assert(scope.IsValid);

                foreach (var field in scope.GetNames(DPath.Root))
                {
                    IntellisenseHelper.AddSuggestion(intellisenseData, TexlLexer.PunctuatorAt + TexlLexer.EscapeName(field.Name.Value), SuggestionKind.Field, SuggestionIconKind.Other, field.Type, requiresSuggestionEscaping: false);
                }
            }
Beispiel #5
0
        // This method returns the suggestions for latter arguments of the If function based on the second argument (the true result)
        private static IEnumerable <KeyValuePair <string, DType> > IfSuggestions(TryGetEnumSymbol tryGetEnumSymbol, bool suggestUnqualifedEnums, DType scopeType, int argumentIndex, out bool requiresSuggestionEscaping)
        {
            Contracts.Assert(scopeType.IsValid);
            Contracts.Assert(0 <= argumentIndex);

            requiresSuggestionEscaping = false;

            if (argumentIndex <= 1)
            {
                return(EnumerableUtils.Yield <KeyValuePair <string, DType> >());
            }

            return(scopeType
                   .GetNames(DPath.Root)
                   .Select(name => new KeyValuePair <string, DType>(TexlLexer.EscapeName(name.Name.Value), name.Type)));
        }
Beispiel #6
0
        public EnumSymbol(DName name, DName invariantName, DType invariantType)
        {
            Contracts.AssertValid(invariantName);
            Contracts.Assert(invariantType.IsEnum);

            Name          = name;
            InvariantName = invariantName;
            EnumType      = invariantType;

            // Initialize the locale-specific enum values, and the loc<->invariant maps.
            _valuesInvariantToLoc         = new Dictionary <string, string>();
            _valuesLocToInvariant         = new Dictionary <string, string>();
            _valuesInvariantToDisplayName = new Dictionary <string, string>();

            foreach (var typedName in EnumType.GetNames(DPath.Root))
            {
                string invName = typedName.Name.Value;

                string locName;
                if (!StringResources.TryGet($"{InvariantName}_{typedName.Name.Value}_Name", out locName))
                {
                    locName = invName;
                }

                Contracts.Assert(DName.IsValidDName(invName));
                _valuesInvariantToLoc[invName] = locName;
                _valuesLocToInvariant[locName] = invName;

                string displayName;
                if (!StringResources.TryGet($"{InvariantName}_{typedName.Name.Value}_DisplayName", out displayName))
                {
                    displayName = locName;
                }

                string custDisplayName;
                string entityNameValue = name.Value;
                if (!EnumStore.TryGetLocalizedEnumValue(entityNameValue, invName, out custDisplayName))
                {
                    custDisplayName = displayName;
                }

                _valuesInvariantToDisplayName[invName] = custDisplayName;
            }
        }
Beispiel #7
0
        internal static void AddSuggestionsForNamesInType(DType type, IntellisenseData.IntellisenseData data, bool createTableSuggestion)
        {
            Contracts.AssertValid(type);
            Contracts.AssertValue(data);

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

                DType suggestionType = field.Type;
                if (createTableSuggestion)
                {
                    suggestionType = DType.CreateTable(new TypedName(type, usedName));
                }

                AddSuggestion(data, usedName.Value, SuggestionKind.Field, SuggestionIconKind.Other, suggestionType, requiresSuggestionEscaping: true);
            }
        }
Beispiel #8
0
        internal static string GenerateColumnNamesMappingForSortByColumns(DType sourceType)
        {
            Contracts.Assert(sourceType.IsTable);

            var    allColumns = sourceType.GetNames(DPath.Root);
            string separator  = string.Empty;

            var primitiveColumnsAndComparatorIds = new StringBuilder();

            primitiveColumnsAndComparatorIds.Append("{");

            foreach (var column in allColumns)
            {
                if (column.Type.IsPrimitive && !column.Type.IsOptionSet)
                {
                    primitiveColumnsAndComparatorIds.AppendFormat("{0}\"{1}\":{2}", separator, CharacterUtils.EscapeString(column.Name),
                                                                  GetSortComparatorIdForType(column.Type));
                    separator = ",";
                }
            }
            primitiveColumnsAndComparatorIds.Append("}");

            return(primitiveColumnsAndComparatorIds.ToString());
        }
Beispiel #9
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));
            }