Exemple #1
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);

            Contracts.Assert(returnType.IsTable);

            returnType = argTypes[0];

            DType exprType = argTypes[1];

            if (!exprType.IsPrimitive || exprType.IsOptionSet)
            {
                fValid = false;
                errors.EnsureError(args[1], TexlStrings.ErrSortWrongType);
            }

            if (args.Length == 3 && argTypes[2] != DType.String)
            {
                fValid = false;
                errors.EnsureError(args[2], TexlStrings.ErrSortIncorrectOrder);
            }

            return(fValid);
        }
Exemple #2
0
 public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span newSpan)
 {
     Contracts.AssertValue(newNodes);
     Contracts.AssertAllValues(newNodes.Values);
     Contracts.AssertAllValues(newNodes.Keys);
     return(new TokenSource(Token.Clone(newSpan)));
 }
Exemple #3
0
 public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span newSpan)
 {
     Contracts.AssertValue(newNodes);
     Contracts.AssertAllValues(newNodes.Values);
     Contracts.AssertAllValues(newNodes.Keys);
     return(new WhitespaceSource(Tokens.Select(token => token.Clone(newSpan))));
 }
Exemple #4
0
        public override bool CheckInvocation(TexlBinding binding, TexlNode[] args, DType[] argTypes, IErrorContainer errors, out DType returnType, out Dictionary <TexlNode, DType> nodeToCoercedTypeMap)
        {
            Contracts.AssertValue(binding);
            Contracts.AssertValue(args);
            Contracts.AssertAllValues(args);
            Contracts.AssertValue(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.AssertValue(errors);


            // Base call yields unknown return type, so we set it accordingly below
            bool fArgsValid = base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);

            // Return type determined by second argument (function)
            // Since CheckInvocation is called on partial functions, return type should be error when a second argument is undefined
            if (argTypes.Length >= 2)
            {
                returnType = argTypes[1];
            }
            else
            {
                returnType = DType.Error;
            }

            return(fArgsValid);
        }
Exemple #5
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);
        }
Exemple #6
0
        public RecordNode(IRContext irContext, IReadOnlyDictionary <DName, IntermediateNode> fields) : base(irContext)
        {
            Contracts.AssertAllValid(fields.Keys);
            Contracts.AssertAllValues(fields.Values);

            Fields = fields;
        }
Exemple #7
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);

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

            if (argTypes[1].IsRecord)
            {
                returnType = argTypes[1].ToTable();
            }
            else if (argTypes[1].IsPrimitive || argTypes[1].IsTable)
            {
                returnType = DType.CreateTable(new TypedName(argTypes[1], ColumnName_Value));
            }
            else
            {
                returnType = DType.Error;
                fArgsValid = false;
            }

            return(fArgsValid);
        }
Exemple #8
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);

            DType type0 = argTypes[0];
            DType type1 = argTypes[1];

            DType    otherType = DType.Invalid;
            TexlNode otherArg  = null;

            // At least one of the arguments has to be a table.
            if (type0.IsTable)
            {
                // Ensure we have a one-column table of colors.
                fValid &= CheckColorColumnType(type0, args[0], errors, ref nodeToCoercedTypeMap);
                // Borrow the return type from the 1st arg.
                returnType = type0;
                // Check arg1 below.
                otherArg  = args[1];
                otherType = type1;

                fValid &= CheckOtherType(otherType, otherArg, DType.Number, errors, ref nodeToCoercedTypeMap);

                Contracts.Assert(returnType.IsTable);
                Contracts.Assert(!fValid || returnType.IsColumn);
            }
            else if (type1.IsTable)
            {
                // Ensure we have a one-column table of numerics.
                fValid &= CheckNumericColumnType(type1, args[1], errors, ref nodeToCoercedTypeMap);
                // Since the 1st arg is not a table, make a new table return type *[Result:c]
                returnType = DType.CreateTable(new TypedName(DType.Color, OneColumnTableResultName));
                // Check arg0 below.
                otherArg  = args[0];
                otherType = type0;

                fValid &= CheckOtherType(otherType, otherArg, DType.Color, errors, ref nodeToCoercedTypeMap);

                Contracts.Assert(returnType.IsTable);
                Contracts.Assert(!fValid || returnType.IsColumn);
            }
            else
            {
                Contracts.Assert(returnType.IsTable);

                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTypeError_Ex1_Ex2_Found, TableKindString, DType.Color.GetKindString(), type0.GetKindString());
                errors.EnsureError(DocumentErrorSeverity.Severe, args[1], TexlStrings.ErrTypeError_Ex1_Ex2_Found, TableKindString, DType.Number.GetKindString(), type1.GetKindString());
                // Both args are invalid. No need to continue.
                return(false);
            }

            return(fValid);
        }
Exemple #9
0
        public override bool CheckInvocation(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);

            nodeToCoercedTypeMap = new Dictionary <TexlNode, DType>();
            int count = args.Length;

            // Check the args.
            bool fArgsValid = true;

            for (int i = 0; i < count; i++)
            {
                fArgsValid &= CheckType(args[i], argTypes[i], DType.Boolean, errors, out var matchedWithCoercion);
                if (matchedWithCoercion)
                {
                    CollectionUtils.Add(ref nodeToCoercedTypeMap, args[i], DType.Boolean);
                }
            }

            returnType = ReturnType;

            return(fArgsValid);
        }
Exemple #10
0
 public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span span)
 {
     Contracts.AssertValue(newNodes);
     Contracts.AssertAllValues(newNodes.Values);
     Contracts.AssertAllValues(newNodes.Keys);
     return(new IdentifierSource(Identifier.Clone(span)));
 }
Exemple #11
0
        public override bool CheckInvocation(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.Assert(args.Length == 1);
            Contracts.AssertValue(errors);

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

            Contracts.Assert(returnType.IsTable);

            var arg     = args[0];
            var argType = argTypes[0];

            fValid &= CheckNumericColumnType(argType, arg, errors, ref nodeToCoercedTypeMap);

            if (nodeToCoercedTypeMap?.Any() ?? false)
            {
                // Now set the coerced type to a table with numeric column type with the same name as in the argument.
                returnType = nodeToCoercedTypeMap[arg];
            }
            else
            {
                returnType = argType;
            }

            if (!fValid)
            {
                nodeToCoercedTypeMap = null;
            }

            return(fValid);
        }
Exemple #12
0
        public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span span)
        {
            Contracts.AssertAllValues(newNodes.Keys);
            Contracts.AssertAllValues(newNodes.Values);
            Contracts.AssertValue(newNodes);

            return(new NodeSource(newNodes[Node]));
        }
Exemple #13
0
        public CallNode(IRContext irContext, TexlFunction func, IList <IntermediateNode> args) : base(irContext)
        {
            Contracts.AssertValue(func);
            Contracts.AssertAllValues(args);

            Function = func;
            Args     = args.ToList();
        }
Exemple #14
0
 // Assumes ownership of the 'children' and 'opTokens' array.
 public VariadicOpNode(ref int idNext, VariadicOp op, TexlNode[] children, Token[] opTokens, SourceList sourceList)
     : base(ref idNext, opTokens.VerifyValue().First(), sourceList, children)
 {
     Contracts.AssertNonEmpty(opTokens);
     Contracts.AssertAllValues(opTokens);
     Op       = op;
     OpTokens = opTokens;
 }
Exemple #15
0
        protected override bool RequiresPagedDataForParamCore(TexlNode[] args, int paramIndex, TexlBinding binding)
        {
            Contracts.AssertValue(args);
            Contracts.AssertAllValues(args);
            Contracts.Assert(0 <= paramIndex && paramIndex < args.Length);
            Contracts.AssertValue(binding);
            Contracts.Assert(binding.IsPageable(args[paramIndex].VerifyValue()));

            // For the second argument, we need only metadata. No actual data from datasource is required.
            return(paramIndex != 1);
        }
Exemple #16
0
        internal static void AddSuggestionsForNamespace(IntellisenseData.IntellisenseData intellisenseData, IEnumerable <TexlFunction> namespaceFunctions)
        {
            Contracts.AssertValue(intellisenseData);
            Contracts.AssertValue(namespaceFunctions);
            Contracts.AssertAllValues(namespaceFunctions);

            foreach (var function in namespaceFunctions)
            {
                // Note we're using the unqualified name, since we're on the RHS of a "namespace." identifier.
                AddSuggestion(intellisenseData, function.Name, SuggestionKind.Function, SuggestionIconKind.Function, function.ReturnType, requiresSuggestionEscaping: true);
            }
        }
Exemple #17
0
        public override bool CheckInvocation(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);

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

            fValid &= CheckAllParamsAreTypeOrSingleColumnTable(DType.Number, args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);

            return(fValid);
        }
Exemple #18
0
        public ITexlSource Clone(Dictionary <TexlNode, TexlNode> newNodes, Span newSpan)
        {
            Contracts.AssertValue(newNodes);
            Contracts.AssertAllValues(newNodes.Values);
            Contracts.AssertAllValues(newNodes.Keys);
            ITexlSource[] newItems = new ITexlSource[Sources.Count()];
            int           i        = 0;

            foreach (var source in Sources)
            {
                newItems[i] = source.Clone(newNodes, newSpan);
                i          += 1;;
            }
            return(new SpreadSource(newItems));
        }
Exemple #19
0
        public SourceList Clone(Span span, Dictionary <TexlNode, TexlNode> newNodes)
        {
            Contracts.AssertValue(newNodes);
            Contracts.AssertAllValues(newNodes.Values);
            Contracts.AssertAllValues(newNodes.Keys);
            ITexlSource[] newItems = new ITexlSource[Sources.Count()];
            int           i        = 0;

            foreach (var source in Sources)
            {
                newItems[i] = source.Clone(newNodes, span);
                i          += 1;
            }
            return(new SourceList(newItems));
        }
Exemple #20
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 == 2);
            Contracts.Assert(argTypes.Length == 2);
            Contracts.AssertValue(errors);


            if (!base.CheckInvocation(binding, args, argTypes, errors, out returnType, out nodeToCoercedTypeMap))
            {
                return(false);
            }

            // Check if first argument is poly type or an activity pointer
            if (!argTypes[0].IsPolymorphic && !argTypes[0].IsActivityPointer)
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrBadType_ExpectedType_ProvidedType, DKind.Polymorphic.ToString(), argTypes[0].GetKindString());
                return(false);
            }

            // Check if table arg referrs to a connected data source.
            TexlNode            tableArg = args[1];
            FirstNameInfo       tableInfo;
            IExternalDataSource tableDsInfo;

            if (!binding.TryGetFirstNameInfo(tableArg.Id, out tableInfo) ||
                (tableDsInfo = (tableInfo.Data as IExternalDataSource)) == null ||
                !(tableDsInfo is IExternalTabularDataSource))
            {
                errors.EnsureError(tableArg, TexlStrings.ErrAsTypeAndIsTypeExpectConnectedDataSource);
                return(false);
            }

            if (binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled && (tableDsInfo is IExternalCdsDataSource) && argTypes[0].HasPolymorphicInfo)
            {
                var expandInfo = argTypes[0].PolymorphicInfo.TryGetExpandInfo(tableDsInfo.TableMetadata.Name);
                if (expandInfo != null)
                {
                    returnType = argTypes[0].ExpandPolymorphic(argTypes[1], expandInfo);
                    return(true);
                }
            }

            returnType = argTypes[1].ToRecord();
            return(true);
        }
Exemple #21
0
        public override bool CheckInvocation(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);

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

            bool fError = false;

            returnType = argTypes[0].ToTable(ref fError);

            return(isValid && !fError);
        }
Exemple #22
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.Assert(args.Length == 2);
            Contracts.AssertValue(errors);

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

            Contracts.Assert(returnType.IsTable);

            returnType = DType.CreateTable(new TypedName(DType.String, OneColumnTableResultName));
            return(fValid);
        }
Exemple #23
0
        // Typecheck an invocation of Table.
        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 isValid = base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);

            Contracts.Assert(returnType.IsTable);

            // Ensure that all args (if any) are records with compatible schemas.
            DType rowType = DType.EmptyRecord;

            for (int i = 0; i < argTypes.Length; i++)
            {
                DType argType = argTypes[i];
                if (!argType.IsRecord)
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrNeedRecord);
                    isValid = false;
                }
                else if (!rowType.CanUnionWith(argType))
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrIncompatibleRecord);
                    isValid = false;
                }
                else
                {
                    bool isUnionError = false;
                    rowType = DType.Union(ref isUnionError, rowType, argType);
                    Contracts.Assert(!isUnionError);
                    Contracts.Assert(rowType.IsRecord);
                }
            }

            Contracts.Assert(rowType.IsRecord);
            returnType = rowType.ToTable();

            return(isValid);
        }
Exemple #24
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);
            DType type0  = argTypes[0];

            // Arg0 should not be a Time
            if (type0.Kind == DKind.Time)
            {
                fValid = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrDateExpected);
            }
            returnType = ReturnType;
            return(fValid);
        }
Exemple #25
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.AssertAllValid(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.AssertValue(errors);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

            nodeToCoercedTypeMap = null;

            bool  isValid = true;
            DType argType = argTypes[0];

            if (!DType.Number.Accepts(argType) && !DType.String.Accepts(argType))
            {
                if (argType.CoercesTo(DType.DateTime) && !argType.IsControl)
                {
                    CollectionUtils.Add(ref nodeToCoercedTypeMap, args[0], DType.DateTime);
                }
                else
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrNumberOrStringExpected);
                    isValid = false;
                }
            }

            if (args.Length > 1)
            {
                argType = argTypes[1];
                if (!DType.String.Accepts(argType))
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[1], TexlStrings.ErrStringExpected);
                    isValid = false;
                }
            }

            returnType = DType.Number;
            return(isValid);
        }
Exemple #26
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);

            Contracts.Assert(returnType.IsTable);

            // Typecheck the input table
            fValid &= CheckStringColumnType(argTypes[0], args[0], errors, ref nodeToCoercedTypeMap);

            // Synthesize a new return type
            returnType = DType.CreateTable(new TypedName(DType.Number, OneColumnTableResultName));

            return(fValid);
        }
Exemple #27
0
        public static ErrorResource Reassemble(Dictionary <string, Dictionary <int, string> > members)
        {
            Contracts.AssertAllNonEmpty(members.Keys);
            Contracts.AssertAllValues(members.Values);

            var errorResource = new ErrorResource();

            // Reassemble link 2-part resources first
            // They need to match up. Because these resources are loaded for almost all tests,
            // The asserts here will fail during unit tests if they're incorrectly defined
            if (members.TryGetValue(LinkTag, out var linkValues))
            {
                members.TryGetValue(LinkTagUrlTag, out var urls).Verify();
                Contracts.Assert(linkValues.Count == urls.Count);

                foreach (var kvp in linkValues)
                {
                    urls.TryGetValue(kvp.Key, out var correspondingUrl).Verify();
                    errorResource.HelpLinks.Add(new ErrorHelpLink(kvp.Value, correspondingUrl));
                }
                members.Remove(LinkTag);
                members.Remove(LinkTagUrlTag);
            }


            foreach (var tag in members)
            {
                if (!errorResource.TagToValues.ContainsKey(tag.Key))
                {
                    errorResource.TagToValues[tag.Key] = new List <string>();
                }

                foreach (var value in tag.Value.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
                {
                    errorResource.TagToValues[tag.Key].Add(value);
                }
            }

            return(errorResource);
        }
Exemple #28
0
        public override bool CheckInvocation(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);

            Contracts.Assert(returnType == DType.Number);

            bool matchedWithCoercion;

            // Ensure that all the arguments are numeric/coercible to numeric.
            for (int i = 0; i < argTypes.Length; i++)
            {
                if (CheckType(args[i], argTypes[i], DType.Number, DefaultErrorContainer, out matchedWithCoercion))
                {
                    if (matchedWithCoercion)
                    {
                        CollectionUtils.Add(ref nodeToCoercedTypeMap, args[i], DType.Number, allowDupes: true);
                    }
                }
                else
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrNumberExpected);
                    fValid = false;
                }
            }

            if (!fValid)
            {
                nodeToCoercedTypeMap = null;
            }

            return(fValid);
        }
Exemple #29
0
        public override bool CheckInvocation(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);

            if (!base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap))
            {
                return(false);
            }

            // Option Set values need to be checked with their own function since they have a special return for "blank" values.
            if (argTypes[0].Kind == DKind.OptionSetValue)
            {
                return(false);
            }

            if (argTypes[0] is IExternalControlType controlType)
            {
                // A control will never be null. It never worked as intended.
                // We coerce the control to control.primaryOutProperty.
                var primaryOutputProperty = controlType.ControlTemplate.VerifyValue().PrimaryOutputProperty;
                Contracts.AssertValueOrNull(primaryOutputProperty);

                if (primaryOutputProperty != null)
                {
                    if (nodeToCoercedTypeMap == null)
                    {
                        nodeToCoercedTypeMap = new Dictionary <TexlNode, DType>();
                    }

                    nodeToCoercedTypeMap.Add(args[0], primaryOutputProperty.GetOpaqueType());
                }
            }

            return(true);
        }
Exemple #30
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);

            Contracts.Assert(returnType == DType.DateTime);

            DType type0 = argTypes[0];

            if (fValid)
            {
                // Arg0 should be either a DateTime or Date.
                if (type0.Kind == DKind.Date)
                {
                    // Max resolution we support right now is "Days". If we start supporting sub-day resolutions
                    // then we need to revisit this and return DateTime in those cases.
                    returnType = DType.Date;
                }
                else if (type0.Kind == DKind.DateTime)
                {
                    returnType = ReturnType;
                }
                else
                {
                    fValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrDateExpected);
                    returnType = ReturnType;
                }
            }

            return(fValid);
        }