public override bool IsServerDelegatable(CallNode callNode, TexlBinding binding) { Contracts.AssertValue(callNode); Contracts.AssertValue(binding); if (FunctionDelegationCapability.Capabilities == DelegationCapability.None) { return(false); } if (!CheckArgsCount(callNode, binding)) { return(false); } IExternalDataSource dataSource; if (!TryGetValidDataSourceForDelegation(callNode, binding, FunctionDelegationCapability, out dataSource)) { if (dataSource != null && dataSource.IsDelegatable) { binding.ErrorContainer.EnsureError(DocumentErrorSeverity.Warning, callNode, TexlStrings.OpNotSupportedByServiceSuggestionMessage_OpNotSupportedByService, Name); } return(false); } var args = callNode.Args.Children.VerifyValue(); if (binding.GetType(args[0]).HasExpandInfo || (!binding.IsFullRecordRowScopeAccess(args[1]) && args[1].Kind != NodeKind.FirstName) || !binding.IsRowScope(args[1]) || binding.GetType(args[1]) != DType.Number || ExpressionContainsView(callNode, binding)) { SuggestDelegationHint(callNode, binding); if (binding.GetType(args[1]) != DType.Number) { DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.NotANumberArgType, callNode, binding, this, DelegationTelemetryInfo.CreateEmptyDelegationTelemetryInfo()); } else { DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.InvalidArgType, callNode, binding, this, DelegationTelemetryInfo.CreateEmptyDelegationTelemetryInfo()); } return(false); } if (binding.IsFullRecordRowScopeAccess(args[1])) { return(GetDottedNameNodeDelegationStrategy().IsValidDottedNameNode(args[1].AsDottedName(), binding, null, null)); } var firstNameStrategy = GetFirstNameNodeDelegationStrategy().VerifyValue(); return(firstNameStrategy.IsValidFirstNameNode(args[1].AsFirstName(), binding, null)); }
public static void LogTelemetryForFunction(TexlFunction function, CallNode node, TexlBinding texlBinding, bool isServerDelegatable) { Contracts.AssertValue(function); Contracts.AssertValue(node); Contracts.AssertValue(texlBinding); // We only want to log about successful delegation status here. Any failures should have been logged by this time. if (isServerDelegatable) { DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.DelegationSuccessful, node, texlBinding, function); return; } }
private bool IsSortOrderSuppportedByColumn(TexlNode node, TexlBinding binding, string order, SortOpMetadata metadata, DPath columnPath) { Contracts.AssertValue(node); Contracts.AssertValue(binding); Contracts.AssertValue(order); Contracts.AssertValue(metadata); Contracts.AssertValid(columnPath); var result = IsSortOrderSuppportedByColumn(order, metadata, columnPath); if (!result) { DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.SortOrderNotSupportedByColumn, node, binding, this, DelegationTelemetryInfo.CreateEmptyDelegationTelemetryInfo()); } return(result); }
private bool IsValidSortOrderNode(TexlNode node, SortOpMetadata metadata, TexlBinding binding, DPath columnPath) { Contracts.AssertValue(node); Contracts.AssertValue(metadata); Contracts.AssertValue(binding); Contracts.AssertValid(columnPath); if (binding.IsAsync(node)) { AddSuggestionMessageToTelemetry("Async sortorder node.", node, binding); DelegationTrackerCore.SetDelegationTrackerStatus(DelegationStatus.AsyncSortOrder, node, binding, this, DelegationTelemetryInfo.CreateEmptyDelegationTelemetryInfo()); return(false); } string sortOrder; switch (node.Kind) { case NodeKind.FirstName: case NodeKind.StrLit: return(_sortOrderValidator.TryGetValidValue(node, binding, out sortOrder) && IsSortOrderSuppportedByColumn(node, binding, sortOrder, metadata, columnPath)); case NodeKind.DottedName: case NodeKind.Call: if (_sortOrderValidator.TryGetValidValue(node, binding, out sortOrder) && IsSortOrderSuppportedByColumn(node, binding, sortOrder, metadata, columnPath)) { return(true); } // If both ascending and descending are supported then we can support this. return(IsSortOrderSuppportedByColumn(node, binding, LanguageConstants.DescendingSortOrderString, metadata, columnPath) && IsSortOrderSuppportedByColumn(node, binding, LanguageConstants.AscendingSortOrderString, metadata, columnPath)); default: AddSuggestionMessageToTelemetry("Unsupported sortorder node kind.", 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); }