Example #1
0
        // Typecheck an input for this function, and get the cursor type for an invocation with that input.
        // arg0 and arg0Type correspond to the input and its type.
        // The cursor type for aggregate functions is generally the type of a row in the input schema (table),
        // for example Table in an invocation Average(Table, valueFunction).
        // Returns true on success, false if the input or its type are invalid with respect to this function's declaration
        // (and populate the error container accordingly).
        public virtual bool CheckInput(TexlNode inputNode, DType inputSchema, IErrorContainer errors, out DType typeScope)
        {
            Contracts.AssertValue(inputNode);
            Contracts.Assert(inputSchema.IsValid);
            Contracts.AssertValue(errors);

            CallNode callNode = inputNode.Parent.CastList().Parent.CastCall();

            Contracts.AssertValue(callNode);

            typeScope = inputSchema;

            bool fArgsValid = true;

            if (_function.ParamTypes.Length == 0)
            {
                switch (typeScope.Kind)
                {
                case DKind.Record:
                    break;

                case DKind.Error:
                    fArgsValid = false;
                    errors.EnsureError(inputNode, TexlStrings.ErrBadType);
                    break;

                default:
                    fArgsValid = false;
                    errors.Error(callNode, TexlStrings.ErrBadType);
                    break;
                }
            }
            else if (_function.ParamTypes[0].IsTable)
            {
                if (!typeScope.IsTable)
                {
                    errors.Error(callNode, TexlStrings.ErrNeedTable_Func, _function.Name);
                    fArgsValid = false;
                }
                // This assumes that the lambdas operate on the individual records
                // of the table, not the entire table.
                bool fError = false;
                typeScope   = typeScope.ToRecord(ref fError);
                fArgsValid &= !fError;
            }
            else
            {
                Contracts.Assert(_function.ParamTypes[0].IsRecord);
                if (!typeScope.IsRecord)
                {
                    errors.Error(callNode, TexlStrings.ErrNeedRecord_Func, _function.Name);
                    bool fError = false;
                    typeScope  = typeScope.ToRecord(ref fError);
                    fArgsValid = false;
                }
            }

            return(fArgsValid);
        }
Example #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.AssertValue(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.AssertValue(errors);

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

            DType arg0Type = argTypes[0];

            if (arg0Type.IsTable)
            {
                returnType = arg0Type.ToRecord();
            }
            else
            {
                returnType = arg0Type.IsRecord ? arg0Type : DType.Error;
                fArgsValid = false;
            }

            return(fArgsValid);
        }