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