Beispiel #1
0
        internal static DType GetEnumType(IntellisenseData.IntellisenseData intellisenseData, TexlNode node)
        {
            Contracts.AssertValue(intellisenseData);
            Contracts.AssertValue(node);

            DottedNameNode dottedNode;
            FirstNameNode  firstNameNode;

            if ((dottedNode = node.AsDottedName()) != null)
            {
                return(intellisenseData.Binding.GetType(dottedNode.Left));
            }

            if ((firstNameNode = node.AsFirstName()) != null)
            {
                FirstNameInfo firstNameInfo = intellisenseData.Binding.GetInfo(firstNameNode).VerifyValue();

                DPath parent = firstNameInfo.Path.Parent;
                if (!parent.Name.IsValid)
                {
                    return(DType.Unknown);
                }

                if (intellisenseData.TryGetEnumSymbol(parent.Name, intellisenseData.Binding, out EnumSymbol enumSymbol))
                {
                    return(enumSymbol.EnumType);
                }
            }

            return(DType.Unknown);
        }
        public bool TryGetValidValue(TexlNode argNode, TexlBinding binding, out IList <FirstNameNode> dsNodes)
        {
            Contracts.AssertValue(argNode);
            Contracts.AssertValue(binding);

            dsNodes = new List <FirstNameNode>();
            FirstNameNode dsNode;

            switch (argNode.Kind)
            {
            case NodeKind.FirstName:
                if (TryGetDsNode(argNode.AsFirstName(), binding, out dsNode))
                {
                    dsNodes.Add(dsNode);
                }
                break;

            case NodeKind.Call:
                return(TryGetDsNodes(argNode.AsCall(), binding, out dsNodes));

            case NodeKind.DottedName:
                return(TryGetDsNode(argNode.AsDottedName(), binding, out dsNodes));
            }

            return(dsNodes.Count > 0);
        }
Beispiel #3
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);
            }
        }
Beispiel #4
0
        // from FunctionUtils.TryGetDataSource
        public static bool TryGetDataSource(this IExternalEntityScope entityScope, TexlNode node, out IExternalDataSource dataSourceInfo)
        {
            Contracts.AssertValue(entityScope);
            Contracts.AssertValue(node);

            FirstNameNode firstNameNode;

            if ((firstNameNode = node.AsFirstName()) == null)
            {
                dataSourceInfo = null;
                return(false);
            }

            return(entityScope.TryGetEntity <IExternalDataSource>(firstNameNode.Ident.Name, out dataSourceInfo));
        }
Beispiel #5
0
        public bool TryGetValidValue(TexlNode argNode, TexlBinding binding, out IExpandInfo entityInfo)
        {
            Contracts.AssertValue(argNode);
            Contracts.AssertValue(binding);

            entityInfo = null;
            switch (argNode.Kind)
            {
            case NodeKind.FirstName:
                return(TryGetEntityInfo(argNode.AsFirstName(), binding, out entityInfo));

            case NodeKind.Call:
                return(TryGetEntityInfo(argNode.AsCall(), binding, out entityInfo));

            case NodeKind.DottedName:
                return(TryGetEntityInfo(argNode.AsDottedName(), binding, out entityInfo));
            }

            return(false);
        }
        public bool TryGetValidValue(TexlNode argNode, TexlBinding binding, out IExternalDataSource dsInfo)
        {
            Contracts.AssertValue(argNode);
            Contracts.AssertValue(binding);

            dsInfo = null;
            switch (argNode.Kind)
            {
            case NodeKind.FirstName:
                return(TryGetDsInfo(argNode.AsFirstName(), binding, out dsInfo));

            case NodeKind.Call:
                return(TryGetDsInfo(argNode.AsCall(), binding, out dsInfo));

            case NodeKind.DottedName:
                return(TryGetDsInfo(argNode.AsDottedName(), binding, out dsInfo));

            case NodeKind.As:
                return(TryGetValidValue(argNode.AsAsNode().Left, binding, out dsInfo));
            }

            return(false);
        }
            private static bool TryGetNamespaceFunctions(TexlNode node, TexlBinding binding, out IEnumerable <TexlFunction> functions)
            {
                Contracts.AssertValue(node);
                Contracts.AssertValue(binding);

                FirstNameNode curNode = node.AsFirstName();

                if (curNode == null)
                {
                    functions = EmptyEnumerator <TexlFunction> .Instance;
                    return(false);
                }

                FirstNameInfo firstNameInfo = binding.GetInfo(curNode).VerifyValue();

                Contracts.AssertValid(firstNameInfo.Name);

                DPath namespacePath = new DPath().Append(firstNameInfo.Name);

                functions = binding.NameResolver.LookupFunctionsInNamespace(namespacePath);

                return(functions.Any());
            }
            private static bool TryGetEnumInfo(IntellisenseData.IntellisenseData data, TexlNode node, TexlBinding binding, out EnumSymbol enumSymbol)
            {
                Contracts.AssertValue(node);
                Contracts.AssertValue(binding);

                FirstNameNode curNode = node.AsFirstName();

                if (curNode == null)
                {
                    enumSymbol = null;
                    return(false);
                }

                FirstNameInfo firstNameInfo = binding.GetInfo(curNode).VerifyValue();

                if (firstNameInfo.Kind != BindKind.Enum)
                {
                    enumSymbol = null;
                    return(false);
                }

                return(data.TryGetEnumSymbol(firstNameInfo.Name, binding, out enumSymbol));
            }
Beispiel #9
0
        private bool TryGetValidSortOrderNode(DottedNameNode node, TexlBinding binding, out string sortOrder)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);

            sortOrder = "";
            TexlNode lhsNode   = node.Left;
            var      orderEnum = lhsNode.AsFirstName();

            if (orderEnum == null)
            {
                return(false);
            }

            // Verify order enum
            if (!VerifyFirstNameNodeIsValidSortOrderEnum(orderEnum, binding))
            {
                return(false);
            }

            string order = node.Right.Name.Value;

            return(IsValidOrderString(order, out sortOrder));
        }
        // Verifies if given kind of node is supported by function delegation.
        private bool IsSupportedNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding, IOpDelegationStrategy opDelStrategy, bool isRHSNode)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(opDelStrategy);

            if (!binding.IsRowScope(node))
            {
                // Check whether this is -
                //  1) in operator delegation and
                //  2) it is verifying if RHS node is supported and
                //  3) it is not an async node and
                //  4) it is a single column table and
                //  5) metadata belongs to cds datasource that supports delegation of CdsIn
                // If this check fails, verify if it is simply a valid node..
                // Eg of valid delegation functions -
                // Filter(Accounts, 'Account Name' in ["Foo", Bar"]) - Direct table use
                // Set(Names, ["Foo", Bar"]); Filter(Accounts, 'Account Name' in Names) - Using variable of type table
                // ClearCollect(Names, Accounts); Filter(Accounts, 'Account Name' in Names.'Account Name') - using column from collection.
                // This won't be delegated - Filter(Accounts, 'Account Name' in Accounts.'Account Name') as Accounts.'Account Name' is async.
                if ((binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled &&
                     isRHSNode && (opDelStrategy as BinaryOpDelegationStrategy)?.Op == BinaryOp.In && !binding.IsAsync(node) && binding.GetType(node).IsTable&& binding.GetType(node).IsColumn&&
                     metadata.IsDelegationSupportedByTable(DelegationCapability.CdsIn)) ||
                    IsValidNode(node, binding))
                {
                    return(true);
                }
            }

            switch (node.Kind)
            {
            case NodeKind.DottedName:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var dottedNodeValStrategy = _function.GetDottedNameNodeDelegationStrategy();
                return(dottedNodeValStrategy.IsValidDottedNameNode(node.AsDottedName(), binding, metadata, opDelStrategy));
            }

            case NodeKind.Call:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var cNodeValStrategy = _function.GetCallNodeDelegationStrategy();
                return(cNodeValStrategy.IsValidCallNode(node.AsCall(), binding, metadata));
            }

            case NodeKind.FirstName:
            {
                var firstNameNodeValStrategy = _function.GetFirstNameNodeDelegationStrategy();
                return(firstNameNodeValStrategy.IsValidFirstNameNode(node.AsFirstName(), binding, opDelStrategy));
            }

            case NodeKind.UnaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var unaryopNode = node.AsUnaryOpLit();
                IOpDelegationStrategy unaryOpNodeDelegationStrategy = _function.GetOpDelegationStrategy(unaryopNode.Op);
                return(unaryOpNodeDelegationStrategy.IsSupportedOpNode(unaryopNode, metadata, binding));
            }

            case NodeKind.BinaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var binaryOpNode = node.AsBinaryOp().VerifyValue();
                opDelStrategy = _function.GetOpDelegationStrategy(binaryOpNode.Op, binaryOpNode);

                var binaryOpDelStrategy = (opDelStrategy as BinaryOpDelegationStrategy).VerifyValue();
                Contracts.Assert(binaryOpNode.Op == binaryOpDelStrategy.Op);

                if (!opDelStrategy.IsSupportedOpNode(node, metadata, binding))
                {
                    SuggestDelegationHint(binaryOpNode, binding);
                    return(false);
                }

                break;
            }

            default:
            {
                var kind = node.Kind;
                if (kind != NodeKind.BoolLit && kind != NodeKind.StrLit && kind != NodeKind.NumLit)
                {
                    var telemetryMessage = string.Format("NodeKind {0} unsupported.", kind);
                    SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage);
                    return(false);
                }

                break;
            }
            }

            return(true);
        }
        private bool IsSupportedNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding, IOpDelegationStrategy opDelStrategy)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(metadata);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(opDelStrategy);

            if (!binding.IsRowScope(node))
            {
                return(true);
            }

            switch (node.Kind)
            {
            case NodeKind.DottedName:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var dottedNodeValStrategy = _function.GetDottedNameNodeDelegationStrategy();
                return(dottedNodeValStrategy.IsValidDottedNameNode(node.AsDottedName(), binding, metadata, opDelStrategy));
            }

            case NodeKind.Call:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var cNodeValStrategy = _function.GetCallNodeDelegationStrategy();
                return(cNodeValStrategy.IsValidCallNode(node.AsCall(), binding, metadata));
            }

            case NodeKind.FirstName:
            {
                var firstNameNodeValStrategy = _function.GetFirstNameNodeDelegationStrategy();
                return(firstNameNodeValStrategy.IsValidFirstNameNode(node.AsFirstName(), binding, opDelStrategy));
            }

            case NodeKind.UnaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                UnaryOpNode unaryOpNode = node.AsUnaryOpLit().VerifyValue();
                opDelStrategy = _function.GetOpDelegationStrategy(unaryOpNode.Op).VerifyValue();

                var unaryOpDelStrategy = (opDelStrategy as UnaryOpDelegationStrategy).VerifyValue();
                Contracts.Assert(unaryOpDelStrategy.Op == unaryOpNode.Op);

                if (!opDelStrategy.IsSupportedOpNode(node, metadata, binding))
                {
                    SuggestDelegationHint(node, binding);
                    return(false);
                }

                return(true);
            }

            case NodeKind.BinaryOp:
            {
                if (!opDelStrategy.IsOpSupportedByTable(metadata, node, binding))
                {
                    return(false);
                }

                var binaryOpNode = node.AsBinaryOp().VerifyValue();
                IOpDelegationStrategy binaryOpNodeDelValidationStrategy = _function.GetOpDelegationStrategy(binaryOpNode.Op, binaryOpNode);
                return(binaryOpNodeDelValidationStrategy.IsSupportedOpNode(node.AsBinaryOp(), metadata, binding));
            }
            }

            SuggestDelegationHint(node, binding);
            return(false);
        }
Beispiel #12
0
        public override bool IsServerDelegatable(CallNode callNode, TexlBinding binding)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);

            if (!CheckArgsCount(callNode, binding))
            {
                return(false);
            }

            SortOpMetadata      metadata           = null;
            IDelegationMetadata delegationMetadata = null;
            IExternalDataSource dataSource;

            if (TryGetEntityMetadata(callNode, binding, out delegationMetadata))
            {
                if (!binding.Document.Properties.EnabledFeatures.IsEnhancedDelegationEnabled ||
                    !TryGetValidDataSourceForDelegation(callNode, binding, DelegationCapability.ArrayLookup, out _))
                {
                    SuggestDelegationHint(callNode, binding);
                    return(false);
                }

                metadata = delegationMetadata.SortDelegationMetadata.VerifyValue();
            }
            else
            {
                if (!TryGetValidDataSourceForDelegation(callNode, binding, DelegationCapability.Sort, out dataSource))
                {
                    return(false);
                }

                metadata = dataSource.DelegationMetadata.SortDelegationMetadata;
            }

            TexlNode[] args = callNode.Args.Children.VerifyValue();
            TexlNode   arg1 = args[1].VerifyValue();

            // For now, we are only supporting delegation for Sort operations where second argument is column name.
            // For example, Sort(CDS, Value)
            FirstNameNode firstName = arg1.AsFirstName();

            if (firstName == null)
            {
                SuggestDelegationHint(arg1, binding);
                AddSuggestionMessageToTelemetry("Arg1 is not a FirstName node.", arg1, binding);
                DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.UnSupportedSortArg, arg1, binding, this, DelegationTelemetryInfo.CreateEmptyDelegationTelemetryInfo());
                return(false);
            }

            FirstNameInfo firstNameInfo = binding.GetInfo(firstName);

            if (firstNameInfo == null)
            {
                return(false);
            }

            DPath columnName = DPath.Root.Append(firstNameInfo.Name);

            if (!metadata.IsDelegationSupportedByColumn(columnName, DelegationCapability.Sort))
            {
                SuggestDelegationHint(firstName, binding);
                DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, firstName, binding, this, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(firstNameInfo));
                return(false);
            }

            const string defaultSortOrder = LanguageConstants.AscendingSortOrderString;
            int          cargs            = args.Count();

            // Verify that the third argument (If present) is an Enum or string literal.
            if (cargs < 3 && IsSortOrderSuppportedByColumn(callNode, binding, defaultSortOrder, metadata, columnName))
            {
                return(true);
            }

            // TASK: 6237100 - Binder: Propagate errors in subtree of the callnode to the call node itself
            // Only FirstName, DottedName and StrLit non-async nodes are supported for arg2.
            TexlNode arg2 = args[2].VerifyValue();

            if (!IsValidSortOrderNode(arg2, metadata, binding, columnName))
            {
                SuggestDelegationHint(arg2, binding);
                return(false);
            }

            return(true);
        }
Beispiel #13
0
        protected bool IsValidDelegatableFilterPredicateNode(TexlNode dsNode, TexlBinding binding, FilterOpMetadata filterMetadata)
        {
            Contracts.AssertValue(dsNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(filterMetadata);

            var firstNameStrategy  = GetFirstNameNodeDelegationStrategy();
            var dottedNameStrategy = GetDottedNameNodeDelegationStrategy();
            var cNodeStrategy      = GetCallNodeDelegationStrategy();

            NodeKind kind;

            kind = dsNode.Kind;

            switch (kind)
            {
            case NodeKind.BinaryOp:
            {
                BinaryOpNode opNode = dsNode.AsBinaryOp();
                var          binaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op, opNode);
                Contracts.AssertValue(opNode);

                if (!binaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, filterMetadata, binding))
                {
                    return(false);
                }

                break;
            }

            case NodeKind.FirstName:
            {
                if (!firstNameStrategy.IsValidFirstNameNode(dsNode.AsFirstName(), binding, null))
                {
                    return(false);
                }

                break;
            }

            case NodeKind.DottedName:
            {
                if (!dottedNameStrategy.IsValidDottedNameNode(dsNode.AsDottedName(), binding, filterMetadata, null))
                {
                    return(false);
                }

                break;
            }

            case NodeKind.UnaryOp:
            {
                UnaryOpNode opNode = dsNode.AsUnaryOpLit();
                var         unaryOpNodeValidationStrategy = GetOpDelegationStrategy(opNode.Op);
                Contracts.AssertValue(opNode);

                if (!unaryOpNodeValidationStrategy.IsSupportedOpNode(opNode, filterMetadata, binding))
                {
                    SuggestDelegationHint(dsNode, binding);
                    return(false);
                }

                break;
            }

            case NodeKind.Call:
            {
                if (!cNodeStrategy.IsValidCallNode(dsNode.AsCall(), binding, filterMetadata))
                {
                    return(false);
                }

                break;
            }

            default:
            {
                if (kind != NodeKind.BoolLit)
                {
                    SuggestDelegationHint(dsNode, binding, string.Format("Not supported node {0}.", kind));
                    return(false);
                }

                break;
            }
            }

            return(true);
        }