Esempio n. 1
0
        private bool TryGetValidSortOrder(TexlNode argNode, TexlBinding binding, out string validatedOrder)
        {
            Contracts.AssertValue(argNode);
            Contracts.AssertValue(binding);

            validatedOrder = "";
            if (binding.ErrorContainer.HasErrors(argNode))
            {
                return(false);
            }

            switch (argNode.Kind)
            {
            case NodeKind.FirstName:
                return(TryGetValidSortOrderNode(argNode.AsFirstName(), binding, out validatedOrder));

            case NodeKind.DottedName:
                return(TryGetValidSortOrderNode(argNode.AsDottedName(), binding, out validatedOrder));

            case NodeKind.StrLit:
                return(TryGetValidSortOrderNode(argNode.AsStrLit(), out validatedOrder));

            default:
                TrackingProvider.Instance.AddSuggestionMessage("Invalid sortorder node type", argNode, binding);
                return(false);
            }
        }
Esempio n. 2
0
        private bool IsValidSortableColumnNode(TexlNode node, TexlBinding binding, SortOpMetadata metadata)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(node) || node.Kind != NodeKind.StrLit)
            {
                return(false);
            }

            var columnName = node.AsStrLit().VerifyValue();

            return(IsColumnSortable(columnName, binding, metadata));
        }
Esempio n. 3
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);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

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

            // The first arg determines the scope type for the lambda params, and the return type.
            DType typeScope;

            fArgsValid &= ScopeInfo.CheckInput(args[0], argTypes[0], errors, out typeScope);
            Contracts.Assert(typeScope.IsRecord);

            // The result type has N additional columns, as specified by (args[1],args[2]), (args[3],args[4]), ... etc.
            returnType = typeScope.ToTable();

            int count = args.Length;

            if ((count & 1) == 0)
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0].Parent.CastList().Parent.CastCall(), TexlStrings.ErrBadArityOdd, count);
            }

            for (var i = 1; i < count; i += 2)
            {
                TexlNode nameArg     = args[i];
                DType    nameArgType = argTypes[i];

                // Verify we have a string literal for the column name. Accd to spec, we don't support
                // arbitrary expressions that evaluate to string values, because these values contribute to
                // type analysis, so they need to be known upfront (before AddColumns executes).
                StrLitNode nameNode;
                if (nameArgType.Kind != DKind.String ||
                    (nameNode = nameArg.AsStrLit()) == null)
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrExpectedStringLiteralArg_Name, nameArg.ToString());
                    continue;
                }

                // Verify that the name is valid.
                if (!DName.IsValidDName(nameNode.Value))
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value);
                    continue;
                }

                DName  columnName = new DName(nameNode.Value);
                string colName;
                if (DType.TryGetDisplayNameForColumn(typeScope, columnName, out colName))
                {
                    columnName = new DName(colName);
                }

                // Verify that the name doesn't already exist as either a logical or display name
                DType  columnType;
                string unused;
                if (typeScope.TryGetType(columnName, out columnType) || DType.TryGetLogicalNameForColumn(typeScope, columnName, out unused))
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Moderate, nameArg, TexlStrings.ErrColExists_Name, columnName);
                    continue;
                }

                if (i + 1 >= count)
                {
                    break;
                }

                columnType = argTypes[i + 1];

                // Augment the result type to include the specified column, and verify that it
                // hasn't been specified already within the same invocation.
                bool fError = false;
                returnType = returnType.Add(ref fError, DPath.Root, columnName, columnType);
                if (fError)
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Moderate, nameArg, TexlStrings.ErrColConflict_Name, columnName);
                    continue;
                }
            }

            return(fArgsValid);
        }
Esempio n. 4
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);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

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

            Contracts.Assert(returnType.IsTable);

            if (!argTypes[0].IsTable)
            {
                fArgsValid = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrNeedTable_Func, Name);
            }
            else
            {
                returnType = argTypes[0];
            }

            // The result type has N fewer columns, as specified by (args[1],args[2],args[3],...)
            int count = args.Length;

            for (var i = 1; i < count; i++)
            {
                TexlNode nameArg     = args[i];
                DType    nameArgType = argTypes[i];

                // Verify we have a string literal for the column name. Accd to spec, we don't support
                // arbitrary expressions that evaluate to string values, because these values contribute to
                // type analysis, so they need to be known upfront (before DropColumns executes).
                StrLitNode nameNode;
                if (nameArgType.Kind != DKind.String || (nameNode = nameArg.AsStrLit()) == null)
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrExpectedStringLiteralArg_Name, nameArg.ToString());
                    continue;
                }

                // Verify that the name is valid.
                if (!DName.IsValidDName(nameNode.Value))
                {
                    fArgsValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value);
                    continue;
                }

                DName columnName = new DName(nameNode.Value);

                // Verify that the name exists.
                DType columnType;
                if (!returnType.TryGetType(columnName, out columnType))
                {
                    fArgsValid = false;
                    returnType.ReportNonExistingName(FieldNameKind.Logical, errors, columnName, nameArg);
                    continue;
                }

                // Drop the specified column from the result type.
                bool fError = false;
                returnType = returnType.Drop(ref fError, DPath.Root, columnName);
                Contracts.Assert(!fError);
            }

            return(fArgsValid);
        }
Esempio n. 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);

            Contracts.Assert(returnType.IsTable);

            returnType = argTypes[0];

            DType sourceType = argTypes[0];

            for (int i = 1; i < args.Length; i += 2)
            {
                TexlNode   colNameArg     = args[i];
                DType      colNameArgType = argTypes[i];
                StrLitNode nameNode;

                if (colNameArgType.Kind != DKind.String)
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, colNameArg, TexlStrings.ErrStringExpected);
                    fValid = false;
                }
                else if ((nameNode = colNameArg.AsStrLit()) != null)
                {
                    // Verify that the name is valid.
                    if (DName.IsValidDName(nameNode.Value))
                    {
                        DName columnName = new DName(nameNode.Value);

                        // Verify that the name exists.
                        DType columnType;
                        if (!sourceType.TryGetType(columnName, out columnType))
                        {
                            sourceType.ReportNonExistingName(FieldNameKind.Logical, errors, columnName, args[i]);
                            fValid = false;
                        }
                        else if (!columnType.IsPrimitive || columnType.IsOptionSet)
                        {
                            fValid = false;
                            errors.EnsureError(colNameArg, TexlStrings.ErrSortWrongType);
                        }
                    }
                    else
                    {
                        errors.EnsureError(DocumentErrorSeverity.Severe, nameNode, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value);
                        fValid = false;
                    }
                }

                int nextArgIdx = i + 1;
                if (nextArgIdx < args.Length && argTypes[nextArgIdx] != DType.String)
                {
                    fValid = false;
                    errors.EnsureError(args[i + 1], TexlStrings.ErrSortIncorrectOrder);
                }
            }

            return(fValid);
        }
Esempio n. 6
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      sourceType  = argTypes[0];
            TexlNode   nameArg     = args[1];
            DType      nameArgType = argTypes[1];
            StrLitNode nameNode    = null;
            DType      columnType  = DType.Invalid;

            if (nameArgType.Kind != DKind.String)
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrStringExpected);
                fValid = false;
            }
            else if ((nameNode = nameArg.AsStrLit()) != null)
            {
                // Verify that the name is valid.
                if (DName.IsValidDName(nameNode.Value))
                {
                    DName columnName = new DName(nameNode.Value);

                    // Verify that the name exists.
                    if (!sourceType.TryGetType(columnName, out columnType))
                    {
                        sourceType.ReportNonExistingName(FieldNameKind.Logical, errors, columnName, nameNode);
                        fValid = false;
                    }
                    else if (!columnType.IsPrimitive)
                    {
                        fValid = false;
                        errors.EnsureError(nameArg, TexlStrings.ErrSortWrongType);
                    }
                }
                else
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameNode, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value);
                    fValid = false;
                }
            }

            TexlNode valuesArg = args[2];
            IEnumerable <TypedName> columns;

            if ((columns = argTypes[2].GetNames(DPath.Root)).Count() != 1)
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, valuesArg, TexlStrings.ErrInvalidSchemaNeedCol);
                return(false);
            }

            TypedName column = columns.Single();

            if (nameNode != null && columnType.IsValid && !columnType.Accepts(column.Type))
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, valuesArg, TexlStrings.ErrTypeError_Arg_Expected_Found, nameNode.Value,
                                   columnType.GetKindString(), column.Type.GetKindString());
                fValid = false;
            }

            return(fValid);
        }
Esempio n. 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.AssertValue(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.AssertValue(errors);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

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

            Contracts.Assert(returnType.IsTable);

            if (!argTypes[0].IsTable)
            {
                isValidInvocation = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrNeedTable_Func, Name);
            }
            else
            {
                returnType = argTypes[0];
            }

            DType colsToKeep = DType.EmptyTable;

            // The result type has N columns, as specified by (args[1],args[2],args[3],...)
            int count = args.Length;

            for (var i = 1; i < count; i++)
            {
                TexlNode nameArg     = args[i];
                DType    nameArgType = argTypes[i];

                // Verify we have a string literal for the column name. Accd to spec, we don't support
                // arbitrary expressions that evaluate to string values, because these values contribute to
                // type analysis, so they need to be known upfront (before ShowColumns executes).
                StrLitNode nameNode;
                if (nameArgType.Kind != DKind.String || (nameNode = nameArg.AsStrLit()) == null)
                {
                    isValidInvocation = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrExpectedStringLiteralArg_Name, nameArg.ToString());
                    continue;
                }

                // Verify that the name is valid.
                if (!DName.IsValidDName(nameNode.Value))
                {
                    isValidInvocation = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value);
                    continue;
                }

                DName columnName = new DName(nameNode.Value);

                // Verify that the name exists.
                DType columnType;
                if (!returnType.TryGetType(columnName, out columnType))
                {
                    isValidInvocation = false;
                    returnType.ReportNonExistingName(FieldNameKind.Logical, errors, columnName, args[i]);
                    continue;
                }

                // Verify that the name was only specified once.
                DType existingColumnType;
                if (colsToKeep.TryGetType(columnName, out existingColumnType))
                {
                    isValidInvocation = false;
                    errors.EnsureError(DocumentErrorSeverity.Warning, nameArg, TexlStrings.WarnColumnNameSpecifiedMultipleTimes_Name, columnName);
                    continue;
                }

                // Make a note of which columns are being kept.
                Contracts.Assert(columnType.IsValid);
                colsToKeep = colsToKeep.Add(columnName, columnType);
            }

            // Drop everything but the columns that need to be kept.
            returnType = colsToKeep;

            return(isValidInvocation);
        }