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 IDelegationMetadata GetCapabilityMetadata(FirstNameInfo info) { Contracts.AssertValue(info); IDelegationMetadata metadata = null; if (info.Data is DelegationMetadata.DelegationMetadata) { return(info.Data as DelegationMetadata.DelegationMetadata); } if (info.Data is IExpandInfo) { var entityInfo = (info.Data as IExpandInfo).VerifyValue(); Contracts.AssertValue(entityInfo.ParentDataSource); Contracts.AssertValue(entityInfo.ParentDataSource.DataEntityMetadataProvider); var metadataProvider = entityInfo.ParentDataSource.DataEntityMetadataProvider; IDataEntityMetadata entityMetadata; var result = metadataProvider.TryGetEntityMetadata(entityInfo.Identity, out entityMetadata); Contracts.Assert(result); metadata = entityMetadata.VerifyValue().DelegationMetadata.VerifyValue(); } return(metadata); }
public override bool IsSupportedOpNode(TexlNode node, OperationCapabilityMetadata metadata, TexlBinding binding) { Contracts.AssertValue(node); Contracts.AssertValue(metadata); Contracts.AssertValue(binding); BinaryOpNode binaryOpNode = node?.AsBinaryOp(); if (binaryOpNode == null) { return(false); } var isRHSDelegableTable = IsRHSDelegableTable(binding, binaryOpNode, metadata); DName columnName = default; FirstNameInfo info = null; bool isFullyQualifiedFieldAccess = CheckForFullyQualifiedFieldAccess(isRHSDelegableTable, binaryOpNode, binding, node, ref columnName, ref info); if (!isFullyQualifiedFieldAccess) { return(false); } bool isRowScopedOrLambda = IsRowScopedOrLambda(binding, node, info, columnName, metadata); if (!isRowScopedOrLambda) { return(false); } return(base.IsSupportedOpNode(node, metadata, binding)); }
// Verifies if provided column node supports delegation. protected bool IsDelegatableColumnNode(FirstNameNode node, TexlBinding binding, IOpDelegationStrategy opDelStrategy, DelegationCapability capability) { Contracts.AssertValue(node); Contracts.AssertValue(binding); Contracts.AssertValueOrNull(opDelStrategy); Contracts.Assert(binding.IsRowScope(node)); FirstNameInfo firstNameInfo = binding.GetInfo(node.AsFirstName()); if (firstNameInfo == null) { return(false); } IDelegationMetadata metadata = GetCapabilityMetadata(firstNameInfo); // This means that this row scoped field is from some parent scope which is non-delegatable. That should deny delegation at that point. // For this scope, this means that value will be provided from some other source. // For example, AddColumns(CDS, "Column1", LookUp(CDS1, Name in FirstName)) // CDS - *[Name:s], CDS1 - *[FirstName:s] if (metadata == null) { return(true); } var columnName = firstNameInfo.Name; Contracts.AssertValid(columnName); var columnPath = DPath.Root.Append(columnName); if (!metadata.FilterDelegationMetadata.IsDelegationSupportedByColumn(columnPath, capability)) { var safeColumnName = CharacterUtils.MakeSafeForFormatString(columnName.Value); var message = string.Format(StringResources.Get(TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn), safeColumnName); SuggestDelegationHintAndAddTelemetryMessage(node, binding, message, TexlStrings.OpNotSupportedByColumnSuggestionMessage_OpNotSupportedByColumn, safeColumnName); TrackingProvider.Instance.SetDelegationTrackerStatus(DelegationStatus.NoDelSupportByColumn, node, binding, _function, DelegationTelemetryInfo.CreateNoDelSupportByColumnTelemetryInfo(firstNameInfo)); return(false); } // If there is any operator applied on this node then check if column supports operation. if (opDelStrategy != null && !opDelStrategy.IsOpSupportedByColumn(metadata.FilterDelegationMetadata, node.AsFirstName(), columnPath, binding)) { return(false); } return(true); }
public override void Visit(FirstNameNode node) { FirstNameInfo info = _binding.GetInfo(node); var name = node.Ident.Name.Value; // Only include dependencies from the incoming context (Fields) // defined at the top level (NestDst==1) if ((info.NestDst == 1 && info.Kind == BindKind.LambdaField) || (info.Kind == BindKind.ScopeVariable) || (info.Kind == BindKind.PowerFxResolvedObject)) { _vars.Add(name); } base.Visit(node); }
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)); }
public static DelegationTelemetryInfo CreateNoDelSupportByColumnTelemetryInfo(FirstNameInfo info) { Contracts.AssertValue(info); return(new DelegationTelemetryInfo(info.Name)); }
public bool CheckForFullyQualifiedFieldAccess(bool isRHSDelegableTable, BinaryOpNode binaryOpNode, TexlBinding binding, TexlNode node, ref DName columnName, ref FirstNameInfo info) { Contracts.AssertValue(binaryOpNode); Contracts.AssertValue(binding); Contracts.AssertValue(node); // Check for fully qualified field access var firstNameNode = isRHSDelegableTable ? binaryOpNode.Left?.AsFirstName() : binaryOpNode.Right?.AsFirstName(); var dottedNameNode = isRHSDelegableTable ? binaryOpNode.Left?.AsDottedName() : binaryOpNode.Right?.AsDottedName(); if (dottedNameNode != null && dottedNameNode.Left is FirstNameNode possibleScopeAccess && (info = binding.GetInfo(possibleScopeAccess))?.Kind == BindKind.LambdaFullRecord) { columnName = dottedNameNode.Right.Name; }
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); }