Beispiel #1
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);
        }
Beispiel #2
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);
        }
 public void Validate(IErrorContainer container)
 {
     if (A == 0)
     {
         container.Log("A cannot be zero");
     }
 }
Beispiel #4
0
        public void ShowError(Exception exception, IErrorContainer errorContainer)
        {
            if (exception == null)
            {
                return;
            }

            ErrorContainer errorGrid = (ErrorContainer)errorContainer;

            if (!_dispatcher.CheckAccess())
            {
                _dispatcher.BeginInvoke(() => ShowError(exception, errorGrid));
                return;
            }

            ErrorNotification errorNotification = new ErrorNotification();

            errorGrid.RowDefinitions.Add(new RowDefinition {
                Height = GridLength.Auto
            });
            errorNotification.SetValue(Grid.RowProperty, errorGrid.RowDefinitions.Count - 1);
            errorGrid.Children.Add(errorNotification);
            errorGrid.UpdateLayout(); // Force OnApplyTemplate for ErrorNotification

            errorNotification.Show(exception);
        }
Beispiel #5
0
 public void Validate(IErrorContainer container)
 {
     if (A == 0)
     {
         container.Log("A cannot be zero");
     }
 }
Beispiel #6
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);
        }
Beispiel #7
0
        public ApiHelper(IErrorService errorService, IErrorContainer errorContainer,
                         IStringValidator stringValidator)
        {
            _fileMaxSize = 1024 * 1024 * 3;

            _errorService   = errorService;
            _errorContainer = errorContainer;
            //_returnContainer = returnContainer;
            _stringValidator = stringValidator;
        }
Beispiel #8
0
        /// <summary>Shows the exception.</summary>
        /// <param name="exception">The exception.</param>
        protected void ShowException(Exception exception)
        {
            IErrorContainer errorContainer = ErrorContainer;

            if (errorContainer == null)
            {
                IoC.Resolve <IDialogService>().ShowError(exception);
            }
            else
            {
                IoC.Resolve <IDialogService>().ShowError(exception, errorContainer);
            }
        }
        public PlanitPokerService(
            MultiThreadHelper multiThreadHelper,
            IRoomRepository roomRepository, IStoryRepository storyRepository
            , IErrorService errorService, IErrorContainer errorContainer
            )
        {
            _multiThreadHelper = multiThreadHelper;
            _roomRepository    = roomRepository;
            _storyRepository   = storyRepository;

            _errorService   = errorService;
            _errorContainer = errorContainer;
        }
Beispiel #10
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);
        }
Beispiel #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.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);
        }
Beispiel #12
0
        public ArticleController(
            IJWTService jwtService, IApiHelper apiHealper, IArticleService articleService,
            IErrorService errorService, IErrorContainer errorContainer, ILogger <ArticleController> logger)
        {
            //_articleRepository = articleRepository;
            _jwtService     = jwtService;
            _apiHealper     = apiHealper;
            _articleService = articleService;
            _errorService   = errorService;
            _errorContainer = errorContainer;
            _logger         = logger;
            //_webHostEnvironment = webHostEnvironment;

            _errRetrunFactory          = new ErrorObjectReturnFactory();
            _articleShortReturnFactory = new ArticleShortReturnFactory();
            _articleReturnFactory      = new ArticleReturnFactory();
            _boolResultFactory         = new BoolResultFactory();
        }
Beispiel #13
0
        //private static IServiceProvider _serviceProvider;

        //front endpoints



        public PlanitPokerHub(MultiThreadHelper multiThreadHelper,
                              IStringValidator stringValidator, IPlanitPokerService planitPokerService,
                              IPlanitApiHelper apiHealper, IJWTService jwtService, IJWTHasher hasher, IErrorService errorService
                              , IErrorContainer errorContainer)
        {
            _multiThreadHelper  = multiThreadHelper;
            _stringValidator    = stringValidator;
            _planitPokerService = planitPokerService;

            _jwtService     = jwtService;
            _hasher         = hasher;
            _errorService   = errorService;
            _errorContainer = errorContainer;

            _logger = null; //todo

            _apiHealper = apiHealper;
            _apiHealper.InitByHub(this);
        }
Beispiel #14
0
        public void CheckLiteralPredicates(TexlNode[] args, IErrorContainer errors)
        {
            Contracts.AssertValue(args);
            Contracts.AssertValue(errors);

            if (!AcceptsLiteralPredicates)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    if (_function.IsLambdaParam(i))
                    {
                        if (args[i].Kind == NodeKind.BoolLit ||
                            args[i].Kind == NodeKind.NumLit ||
                            args[i].Kind == NodeKind.StrLit)
                        {
                            errors.EnsureError(DocumentErrorSeverity.Warning, args[i], TexlStrings.WarnLiteralPredicate);
                        }
                    }
                }
            }
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
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);
        }
Beispiel #18
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);
            nodeToCoercedTypeMap = null;
            int viewCount = 0;

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

            var dataSourceVisitor = new ViewFilterDataSourceVisitor(binding);

            // Ensure that all the args starting at index 1 are booleans or view
            for (int i = 1; i < args.Length; i++)
            {
                if (argTypes[i].Kind == DKind.ViewValue)
                {
                    if (++viewCount > 1)
                    {
                        // Only one view expected
                        errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrOnlyOneViewExpected);
                        fArgsValid = false;
                        continue;
                    }

                    // Use the visitor to get the datasource info and if a view was already used anywhere in the node tree.
                    args[0].Accept(dataSourceVisitor);
                    var dataSourceInfo = dataSourceVisitor.cdsDataSourceInfo;

                    if (dataSourceVisitor.ContainsViewFilter)
                    {
                        // Only one view expected
                        errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrOnlyOneViewExpected);
                        fArgsValid = false;
                        continue;
                    }

                    if (dataSourceInfo != null)
                    {
                        // Verify the view belongs to the same datasource
                        var viewInfo = argTypes[i].ViewInfo.VerifyValue();
                        if (viewInfo.RelatedEntityName != dataSourceInfo.Name)
                        {
                            errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrViewFromCurrentTableExpected, dataSourceInfo.Name);
                            fArgsValid = false;
                        }
                    }
                    else
                    {
                        errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrBooleanExpected);
                        fArgsValid = false;
                    }

                    continue;
                }
                else if (DType.Boolean.Accepts(argTypes[i]))
                {
                    continue;
                }
                else if (!argTypes[i].CoercesTo(DType.Boolean))
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrBooleanExpected);
                    fArgsValid = false;
                    continue;
                }
            }

            // The first Texl function arg determines the cursor type, 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);
            returnType = typeScope.ToTable();

            return(fArgsValid);
        }
Beispiel #19
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);

            if (argTypes.Length == 2)
            {
                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 numerics
                    fValid &= CheckNumericColumnType(type0, args[0], errors, ref nodeToCoercedTypeMap);
                    // Borrow the return type from the 1st arg
                    returnType = type0;
                    // Check arg1 below.
                    otherArg  = args[1];
                    otherType = type1;
                }
                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:n]
                    returnType = DType.CreateTable(new TypedName(DType.Number, OneColumnTableResultName));
                    // Check arg0 below.
                    otherArg  = args[0];
                    otherType = type0;
                }
                else
                {
                    Contracts.Assert(returnType.IsTable);
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTypeError);
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[1], TexlStrings.ErrTypeError);
                    // Both args are invalid. No need to continue.
                    return(false);
                }

                Contracts.Assert(otherType.IsValid);
                Contracts.AssertValue(otherArg);
                Contracts.Assert(returnType.IsTable);
                Contracts.Assert(!fValid || returnType.IsColumn);

                if (otherType.IsTable)
                {
                    // Ensure we have a one-column table of numerics
                    fValid &= CheckNumericColumnType(otherType, otherArg, errors, ref nodeToCoercedTypeMap);
                }
                else if (!DType.Number.Accepts(otherType))
                {
                    if (otherType.CoercesTo(DType.Number))
                    {
                        CollectionUtils.Add(ref nodeToCoercedTypeMap, otherArg, DType.Number);
                    }
                    else
                    {
                        fValid = false;
                        errors.EnsureError(DocumentErrorSeverity.Severe, otherArg, TexlStrings.ErrTypeError);
                    }
                }
            }
            else
            {
                DType type0 = argTypes[0];

                if (type0.IsTable)
                {
                    // Ensure we have a one-column table of numerics
                    fValid &= CheckNumericColumnType(type0, args[0], errors, ref nodeToCoercedTypeMap);
                    // Borrow the return type from the 1st arg
                    returnType = type0;
                }
                else
                {
                    Contracts.Assert(returnType.IsTable);
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTypeError);
                    return(false);
                }
            }

            return(fValid);
        }
Beispiel #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 == 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);
        }
Beispiel #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.Assert(args.Length == 1);
            Contracts.AssertValue(errors);

            var reifiedError      = ErrorType.ReifiedError();
            var acceptedFields    = reifiedError.GetNames(DPath.Root);
            var requiredKindField = acceptedFields.Where(tn => tn.Name == "Kind").First();

            Contracts.Assert(requiredKindField.Type.IsEnum);
            var optionalFields = acceptedFields.Where(tn => tn.Name != "Kind");

            returnType           = DType.ObjNull;
            nodeToCoercedTypeMap = null;

            var argument     = args[0];
            var argumentType = argTypes[0];

            if (argumentType.Kind != DKind.Record && argumentType.Kind != DKind.Table)
            {
                errors.EnsureError(argument, TexlStrings.ErrBadType);
                return(false);
            }

            // We cache the whole name list regardless of path.
            var names = argumentType.GetNames(DPath.Root).ToArray();

            // First handle required fields (currently only 'Kind')
            if (!names.Any(field => field.Name == requiredKindField.Name))
            {
                // Kind is required, point it out to the maker, and specify the enumeration type.
                errors.EnsureError(
                    argument,
                    TexlStrings.ErrBadSchema_ExpectedType,
                    reifiedError.GetKindString());
                errors.Error(
                    argument,
                    TexlStrings.ErrColumnMissing_ColName_ExpectedType,
                    requiredKindField.Name.Value,
                    "ErrorKind");
                return(false);
            }

            var argumentKindType = names.First(tn => tn.Name == requiredKindField.Name).Type;

            if (!argumentKindType.CoercesTo(requiredKindField.Type))
            {
                errors.EnsureError(
                    argument,
                    TexlStrings.ErrBadSchema_ExpectedType,
                    reifiedError.GetKindString());
                errors.Error(
                    argument,
                    TexlStrings.ErrBadRecordFieldType_FieldName_ExpectedType,
                    requiredKindField.Name.Value,
                    "ErrorKind");
                return(false);
            }

            bool valid = true;

            var record = argument.AsRecord();

            foreach (var name in names)
            {
                if (!acceptedFields.Any(field => field.Name == name.Name))
                {
                    // If they have a record literal, we can position the errors for rejected fields.
                    if (record != null)
                    {
                        errors.EnsureError(record.Children.Where((_, i) => record.Ids[i].Name == name.Name).FirstOrDefault() ?? record, TexlStrings.ErrErrorIrrelevantField);
                    }
                    else
                    {
                        errors.EnsureError(argument, TexlStrings.ErrErrorIrrelevantField);
                    }
                    valid = false;
                }
            }

            bool matchedWithCoercion;
            bool typeValid;

            if (argumentType.Kind == DKind.Record)
            {
                // A record with the proper types for the fields that are specified.
                var expectedOptionalFieldsRecord = DType.CreateRecord(
                    acceptedFields.Where(field =>
                                         // Kind has already been handled before
                                         field.Name != "Kind" && names.Any(name => name.Name == field.Name)));

                typeValid = CheckType(argument, argumentType, expectedOptionalFieldsRecord, errors, true, out matchedWithCoercion);
            }
            else
            {
                // A table with the proper types for the fields that are specified.
                var expectedOptionalFieldsTable = DType.CreateTable(
                    acceptedFields.Where(field =>
                                         // Kind has already been handled before
                                         field.Name != "Kind" && names.Any(name => name.Name == field.Name)));
                typeValid = CheckType(argument, argumentType, expectedOptionalFieldsTable, errors, true, out matchedWithCoercion);
            }

            if (!typeValid)
            {
                errors.EnsureError(DocumentErrorSeverity.Severe, argument, TexlStrings.ErrTypeError);
                valid = false;
            }
            else if (matchedWithCoercion && valid)
            {
                var recordOrTableSchema   = acceptedFields.Where(field => names.Any(name => name.Name == field.Name));
                var expectedRecordOrTable = argumentType.Kind == DKind.Record ?
                                            DType.CreateRecord(recordOrTableSchema) :
                                            DType.CreateTable(recordOrTableSchema);
                CollectionUtils.Add(ref nodeToCoercedTypeMap, argument, expectedRecordOrTable);
            }

            return(valid);
        }
Beispiel #22
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);
            Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

            int count = args.Length;

            nodeToCoercedTypeMap = null;

            // Check the predicates.
            bool fArgsValid = true;

            for (int i = 0; i < (count & ~1); i += 2)
            {
                bool withCoercion;
                fArgsValid &= CheckType(args[i], argTypes[i], DType.Boolean, errors, true, out withCoercion);

                if (withCoercion)
                {
                    CollectionUtils.Add(ref nodeToCoercedTypeMap, args[i], DType.Boolean);
                }
            }

            DType type = ReturnType;

            // Are we on a behavior property?
            bool isBehavior = binding.IsBehavior;

            // Compute the result type by joining the types of all non-predicate args.
            Contracts.Assert(type == DType.Unknown);
            for (int i = 1; i < count;)
            {
                TexlNode nodeArg = args[i];
                DType    typeArg = argTypes[i];
                if (typeArg.IsError)
                {
                    errors.EnsureError(args[i], TexlStrings.ErrTypeError);
                }

                DType typeSuper = DType.Supertype(type, typeArg);

                if (!typeSuper.IsError)
                {
                    type = typeSuper;
                }
                else if (type.Kind == DKind.Unknown)
                {
                    type       = typeSuper;
                    fArgsValid = false;
                }
                else if (!type.IsError)
                {
                    if (typeArg.CoercesTo(type))
                    {
                        CollectionUtils.Add(ref nodeToCoercedTypeMap, nodeArg, type);
                    }
                    else if (!isBehavior || !IsArgTypeInconsequential(nodeArg))
                    {
                        errors.EnsureError(DocumentErrorSeverity.Severe, nodeArg, TexlStrings.ErrBadType_ExpectedType_ProvidedType,
                                           type.GetKindString(),
                                           typeArg.GetKindString());
                        fArgsValid = false;
                    }
                }
                else if (typeArg.Kind != DKind.Unknown)
                {
                    type       = typeArg;
                    fArgsValid = false;
                }

                // If there are an odd number of args, the last arg also participates.
                i += 2;
                if (i == count)
                {
                    i--;
                }
            }

            // Update the return type based on the specified invocation args.
            returnType = type;

            return(fArgsValid);
        }
Beispiel #23
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 type2 = argTypes[2];

            // Arg0 should be either a string or a column of strings.
            // Its type dictates the function return type.
            if (type0.IsTable)
            {
                // Ensure we have a one-column table of strings
                fValid &= CheckStringColumnType(type0, args[0], errors, ref nodeToCoercedTypeMap);
                // Borrow the return type from the 1st arg
                returnType = type0;
            }
            else
            {
                returnType = DType.CreateTable(new TypedName(DType.String, OneColumnTableResultName));
                if (!DType.String.Accepts(type0))
                {
                    if (type0.CoercesTo(DType.String))
                    {
                        CollectionUtils.Add(ref nodeToCoercedTypeMap, args[0], DType.String);
                    }
                    else
                    {
                        fValid = false;
                        errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrStringExpected);
                    }
                }
            }

            // Arg1 should be either a string or a column of strings.
            if (type1.IsTable)
            {
                fValid &= CheckStringColumnType(type1, args[1], errors, ref nodeToCoercedTypeMap);
            }
            else if (!DType.String.Accepts(type1))
            {
                if (type1.CoercesTo(DType.String))
                {
                    CollectionUtils.Add(ref nodeToCoercedTypeMap, args[1], DType.String);
                }
                else
                {
                    fValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[1], TexlStrings.ErrStringExpected);
                }
            }

            // Arg2 should be either a string or a column of strings.
            if (type2.IsTable)
            {
                fValid &= CheckStringColumnType(type2, args[2], errors, ref nodeToCoercedTypeMap);
            }
            else if (!DType.String.Accepts(type2))
            {
                if (type2.CoercesTo(DType.String))
                {
                    CollectionUtils.Add(ref nodeToCoercedTypeMap, args[2], DType.String);
                }
                else
                {
                    fValid = false;
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[2], TexlStrings.ErrStringExpected);
                }
            }

            bool hasCount = args.Length == 4;

            if (hasCount)
            {
                DType type3 = argTypes[3];

                // Arg3 should be either a number or a column of numbers.
                if (type3.IsTable)
                {
                    fValid &= CheckNumericColumnType(type3, args[3], errors, ref nodeToCoercedTypeMap);
                }
                else if (!DType.Number.Accepts(type3))
                {
                    if (type3.CoercesTo(DType.Number))
                    {
                        CollectionUtils.Add(ref nodeToCoercedTypeMap, args[3], DType.Number);
                    }
                    else
                    {
                        fValid = false;
                        errors.EnsureError(DocumentErrorSeverity.Severe, args[3], TexlStrings.ErrNumberExpected);
                    }
                }
            }

            // At least one arg has to be a table.
            if (!(type0.IsTable || type1.IsTable || type2.IsTable) && (!hasCount || !argTypes[3].IsTable))
            {
                fValid = false;
                errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrTypeError);
                errors.EnsureError(DocumentErrorSeverity.Severe, args[1], TexlStrings.ErrTypeError);
                errors.EnsureError(DocumentErrorSeverity.Severe, args[2], TexlStrings.ErrTypeError);
                if (hasCount)
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[3], TexlStrings.ErrTypeError);
                }
            }

            return(fValid);
        }
 public static Result <T> Fail <T>(IErrorContainer error)
 => new Result <T>(true, default(T), error.Error);
Beispiel #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.AssertValue(argTypes);
            Contracts.Assert(args.Length == argTypes.Length);
            Contracts.Assert(args.Length >= 2);
            Contracts.AssertValue(errors);

            nodeToCoercedTypeMap = null;

            int  count       = args.Length;
            bool hasTableArg = false;
            bool fArgsValid  = true;

            // Type check the args
            // If any one input argument is of table type, then the returnType will be table type.
            for (int i = 0; i < count; i++)
            {
                bool isTable;
                fArgsValid  &= CheckParamIsTypeOrSingleColumnTable(DType.String, args[i], argTypes[i], errors, out isTable, ref nodeToCoercedTypeMap);
                hasTableArg |= isTable;
            }

            returnType = hasTableArg ? DType.CreateTable(new TypedName(DType.String, OneColumnTableResultName)) : DType.String;

            return(fArgsValid);
        }
Beispiel #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.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);
        }
Beispiel #27
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 fValid = base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);

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

            // Ensure that all the args starting at index 1 are booleans.
            for (int i = 1; i < args.Length; i++)
            {
                if (!DType.Boolean.Accepts(argTypes[i]))
                {
                    errors.EnsureError(DocumentErrorSeverity.Severe, args[i], TexlStrings.ErrBooleanExpected);
                    fValid = false;
                }
            }

            return(fValid);
        }
Beispiel #28
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);
        }
Beispiel #29
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);
        }
Beispiel #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);

            // 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 #31
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);
        }