private bool IsUserCallNodeDelegable(TexlNode node, TexlBinding binding) { if ((node is DottedNameNode) && (node.AsDottedName().Left is CallNode) && (binding.GetInfo(node.AsDottedName().Left.AsCall()).Function is ICustomDelegationFunction customDelFunc) && customDelFunc.IsUserCallNodeDelegable()) { return(true); } return(false); }
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); }
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); } }
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); }
protected bool IsValidNode(TexlNode node, TexlBinding binding) { Contracts.AssertValue(node); Contracts.AssertValue(binding); bool isAsync = binding.IsAsync(node); bool isPure = binding.IsPure(node); if (node is DottedNameNode && ((binding.GetType(node.AsDottedName().Left).Kind == DKind.OptionSet && binding.GetType(node).Kind == DKind.OptionSetValue) || (binding.GetType(node.AsDottedName().Left).Kind == DKind.View && binding.GetType(node).Kind == DKind.ViewValue))) { // OptionSet and View Access are delegable despite being async return(true); } if (node is CallNode && (binding.IsBlockScopedConstant(node) || (binding.GetInfo(node as CallNode).Function is AsTypeFunction))) { // AsType is delegable despite being async return(true); } // Async predicates and impure nodes are not supported. // Let CallNodes for User() be marked as being Valid to allow // expressions with User() calls to be delegated if (!(IsUserCallNodeDelegable(node, binding)) && (isAsync || !isPure)) { var telemetryMessage = string.Format("Kind:{0}, isAsync:{1}, isPure:{2}", node.Kind, isAsync, isPure); SuggestDelegationHintAndAddTelemetryMessage(node, binding, telemetryMessage); if (isAsync) { TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.AsyncPredicate, node, binding, _function); } if (!isPure) { TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.ImpureNode, node, binding, _function, DelegationTelemetryInfo.CreateImpureNodeTelemetryInfo(node, binding)); } return(false); } return(true); }
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); }
// 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); }
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); }