public override void Visit(FirstNameNode node)
 {
     if (_txb.EntityScope.TryGetDataSource(node, out var info) && info.Kind == DataSourceKind.CdsNative)
     {
         cdsDataSourceInfo = info as IExternalCdsDataSource;
     }
 }
Exemple #2
0
        // Create a qualified name (global/alias/enum/resource), e.g. "screen1.group25.slider2", or "Color".
        // Can also be used to create fields of ThisItem (with an appropriate upCount).
        public static FirstNameInfo Create(FirstNameNode node, NameLookupInfo lookupInfo)
        {
            Contracts.AssertValue(node);
            Contracts.Assert(lookupInfo.Kind != BindKind.LambdaField && lookupInfo.Kind != BindKind.LambdaFullRecord);
            Contracts.Assert(lookupInfo.UpCount >= 0);
            Contracts.Assert(lookupInfo.Path.IsValid);

            return(new FirstNameInfo(lookupInfo.Kind, node, -lookupInfo.UpCount, 0, lookupInfo.Path, lookupInfo.Data, default, false));
Exemple #3
0
        private bool TryGetEntityInfo(FirstNameNode firstName, TexlBinding binding, out IExpandInfo entityInfo)
        {
            Contracts.AssertValueOrNull(firstName);
            Contracts.AssertValue(binding);

            entityInfo = null;
            if (firstName == null || !binding.GetType(firstName).IsTable)
            {
                return(false);
            }

            return(binding.TryGetEntityInfo(firstName, out entityInfo));
        }
Exemple #4
0
        // 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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        private FirstNameInfo(BindKind kind, FirstNameNode node, int nestDst, int nestCur, DPath path, object data, DName dataControlName, bool isDataControlAccess)
            : base(kind, node)
        {
            Contracts.Assert(nestDst >= int.MinValue);
            Contracts.Assert(nestCur >= 0);
            Contracts.Assert(nestCur >= nestDst);
            Contracts.AssertValueOrNull(data);

            NestDst             = nestDst;
            NestSrc             = nestCur;
            Path                = path;
            Data                = data;
            IsDataControlAccess = isDataControlAccess;
            DataControlName     = dataControlName;

            _dataQueryOptions = new Lazy <Dictionary <ExpandPath, ExpandQueryOptions> >();
        }
Exemple #7
0
        public override LazyList <string> Visit(FirstNameNode node, Precedence parentPrecedence)
        {
            Contracts.AssertValue(node);

            if (node.Ident.AtToken == null)
            {
                return(LazyList <string> .Of(node.Ident.Token.ToString()));
            }
            else
            {
                return(LazyList <string> .Of(
                           TexlLexer.PunctuatorBracketOpen,
                           TexlLexer.PunctuatorAt,
                           node.Ident.Token.ToString(),
                           TexlLexer.PunctuatorBracketClose));
            }
        }
Exemple #8
0
        public override LazyList <string> Visit(FirstNameNode node, Precedence parentPrecedence)
        {
            Contracts.AssertValue(node);

            var info = _binding?.GetInfo(node);

            if (info != null && info.Kind != BindKind.Unknown)
            {
                return(LazyList <string> .Of($"#${Enum.GetName(typeof(BindKind), info.Kind)}$#"));
            }
            if (node.Ident.AtToken == null)
            {
                return(LazyList <string> .Of("#$firstname$#"));
            }
            else
            {
                return(LazyList <string> .Of("#$disambiguation$#"));
            }
        }
            private static bool TryGetLocalScopeInfo(TexlNode node, TexlBinding binding, out ScopedNameLookupInfo info)
            {
                Contracts.AssertValue(node);
                Contracts.AssertValue(binding);

                if (node.Kind == NodeKind.FirstName)
                {
                    FirstNameNode curNode       = node.CastFirstName();
                    var           firstNameInfo = binding.GetInfo(curNode);
                    if (firstNameInfo.Kind == BindKind.ScopeArgument)
                    {
                        info = (ScopedNameLookupInfo)firstNameInfo.Data;
                        return(true);
                    }
                }

                info = new ScopedNameLookupInfo();
                return(false);
            }
Exemple #10
0
        public override bool IsRowScopedServerDelegatable(CallNode callNode, TexlBinding binding, OperationCapabilityMetadata metadata)
        {
            Contracts.AssertValue(callNode);
            Contracts.AssertValue(binding);
            Contracts.AssertValue(metadata);

            if (binding.ErrorContainer.HasErrors(callNode))
            {
                return(false);
            }

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

            TexlNode[] args       = callNode.Args.Children.VerifyValue();
            var        opStrategy = GetOpDelegationStrategy(BinaryOp.Equal, null);

            if (binding.IsFullRecordRowScopeAccess(args[0]))
            {
                return(GetDottedNameNodeDelegationStrategy().IsValidDottedNameNode(args[0] as DottedNameNode, binding, metadata, opStrategy));
            }

            FirstNameNode node = args[0] as FirstNameNode;

            if (node == null)
            {
                var message = string.Format("Arg1 is not a firstname node, instead it is {0}", args[0].Kind);
                AddSuggestionMessageToTelemetry(message, args[0], binding);
                return(false);
            }

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

            var firstNameNodeValidationStrategy = GetFirstNameNodeDelegationStrategy();

            return(firstNameNodeValidationStrategy.IsValidFirstNameNode(node, binding, opStrategy));
        }
Exemple #11
0
        // Parses the RHS of a scope field. E.g., [@bar] in "foo[@bar]"
        private DottedNameNode ParseScopeField(FirstNameNode lhs)
        {
            Contracts.AssertValue(lhs);
            Contracts.Assert(_curs.TidCur == TokKind.BracketOpen);
            Contracts.Assert(_curs.TidPeek() == TokKind.At);

            Token bracketOpen = _curs.TokCur;

            // Parse the rhs of the dotted name
            FirstNameNode rhs = ParseBracketIdentifierAsFirstName();

            // Form the dotted name
            return(new DottedNameNode(
                       ref _idNext,
                       bracketOpen,
                       new SourceList(new NodeSource(lhs), new NodeSource(rhs)),
                       lhs,
                       rhs.Ident,
                       rhs));
        }
        private bool TryGetDsInfo(FirstNameNode firstName, TexlBinding binding, out IExternalDataSource dsInfo)
        {
            Contracts.AssertValueOrNull(firstName);
            Contracts.AssertValue(binding);

            dsInfo = null;
            if (firstName == null || !binding.GetType(firstName).IsTable)
            {
                return(false);
            }

            var firstNameInfo = binding.GetInfo(firstName);

            if (firstNameInfo == null || firstNameInfo.Kind != BindKind.Data)
            {
                return(false);
            }

            return(binding.EntityScope != null &&
                   binding.EntityScope.TryGetEntity(firstNameInfo.Name, out dsInfo));
        }
Exemple #13
0
        public bool IsValidFirstNameNode(FirstNameNode node, TexlBinding binding, IOpDelegationStrategy opDelStrategy)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);
            Contracts.AssertValueOrNull(opDelStrategy);

            var isRowScoped = binding.IsRowScope(node);
            var isValid     = IsValidNode(node, binding);

            if (isValid && !isRowScoped)
            {
                return(true);
            }

            // If invalid node then return immediately.
            if (!isValid)
            {
                return(false);
            }

            return(IsDelegatableColumnNode(node, binding, opDelStrategy, _function.FunctionDelegationCapability));
        }
Exemple #14
0
        private bool TryGetValidSortOrderNode(FirstNameNode node, TexlBinding binding, out string sortOrder)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);

            sortOrder = "";
            var info = binding.GetInfo(node).VerifyValue();

            if (info.Kind != BindKind.Enum)
            {
                return(false);
            }

            string order = info.Data as string;

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

            return(IsValidOrderString(order, out sortOrder));
        }
Exemple #15
0
        private bool VerifyFirstNameNodeIsValidSortOrderEnum(FirstNameNode node, TexlBinding binding)
        {
            Contracts.AssertValue(node);
            Contracts.AssertValue(binding);

            var firstNameInfo = binding.GetInfo(node);

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


            if (!binding.NameResolver.TryLookupEnum(new DName(LanguageConstants.SortOrderEnumStringInvariant), out var lookupInfo))
            {
                return(false);
            }

            DType type = binding.GetType(node);

            return(type == lookupInfo.Type);
        }
            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 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());
            }
            internal override bool TryAddSuggestionsForNodeKind(IntellisenseData.IntellisenseData intellisenseData)
            {
                Contracts.AssertValue(intellisenseData);

                TexlNode curNode   = intellisenseData.CurNode;
                int      cursorPos = intellisenseData.CursorPos;

                FirstNameNode firstNameNode = curNode.CastFirstName();
                Identifier    ident         = firstNameNode.Ident;
                int           min           = ident.Token.Span.Min;
                IdentToken    tok           = ident.Token;

                if (cursorPos < min)
                {
                    // Cursor is before the beginning of the identifier or of the global token if present.
                    // Suggest possibilities that can result in a value.
                    IntellisenseHelper.AddSuggestionsForValuePossibilities(intellisenseData, curNode);
                    intellisenseData.AddAdditionalSuggestionsForKeywordSymbols(curNode);
                }
                else if (cursorPos <= tok.Span.Lim)
                {
                    // Cursor is part of the identifier or global token if present.
                    // Get the matching string as a substring from the script so that the whitespace is preserved.
                    IEnumerable <string> possibleFirstNames = intellisenseData.Binding.GetFirstNames().Select(firstNameInfo => firstNameInfo.Name.Value)
                                                              .Union(intellisenseData.Binding.GetGlobalNames().Select(firstNameInfo => firstNameInfo.Name.Value))
                                                              .Union(intellisenseData.Binding.GetAliasNames().Select(firstNameInfo => firstNameInfo.Name.Value))
                                                              .Union(intellisenseData.SuggestableFirstNames);

                    int replacementLength = IntellisenseHelper.GetReplacementLength(intellisenseData, tok.Span.Min, tok.Span.Lim, possibleFirstNames);
                    intellisenseData.SetMatchArea(tok.Span.Min, cursorPos, replacementLength);
                    intellisenseData.BoundTo = intellisenseData.Binding.ErrorContainer.HasErrors(firstNameNode) ? string.Empty : ident.Name;

                    if (ident.AtToken != null || tok.Kind == TokKind.At)
                    {
                        // Suggest globals if cursor is after '@'.
                        AddSuggestionsForScopedGlobals(intellisenseData);
                    }
                    else if (tok.HasDelimiters && cursorPos > tok.Span.Min)
                    {
                        // Suggest top level fields and globals if cursor is after a opening square bracket.
                        IntellisenseHelper.AddSuggestionsForRuleScope(intellisenseData);
                        IntellisenseHelper.AddSuggestionsForTopLevel(intellisenseData, curNode);
                        IntellisenseHelper.AddSuggestionsForGlobals(intellisenseData);
                        intellisenseData.AddAdditionalSuggestionsForLocalSymbols();
                    }
                    else
                    {
                        // Suggest value posssibilities otherwise.
                        IntellisenseHelper.AddSuggestionsForValuePossibilities(intellisenseData, curNode);
                    }
                    intellisenseData.AddAdditionalSuggestionsForKeywordSymbols(curNode);
                }
                else if (IsBracketOpen(tok.Span.Lim, cursorPos, intellisenseData.Script))
                {
                    AddSuggestionsForScopeFields(intellisenseData, intellisenseData.Binding.GetType(firstNameNode));
                }
                else if (IntellisenseHelper.CanSuggestAfterValue(cursorPos, intellisenseData.Script))
                {
                    // Verify that cursor is after a space after the identifier.
                    // Suggest binary keywords.
                    IntellisenseHelper.AddSuggestionsForAfterValue(intellisenseData, intellisenseData.Binding.GetType(firstNameNode));
                }

                return(true);
            }
 public abstract Result Visit(FirstNameNode node, Context context);
Exemple #20
0
        // Parse a record expression of the form: {id:expr, id:expr, ...}
        // or of the form ident@{id:expr, id:expr}
        private RecordNode ParseRecordExpr(ITexlSource sourceRestrictionTrivia, Identifier sourceRestriction = null)
        {
            Contracts.Assert(_curs.TidCur == TokKind.CurlyOpen || _curs.TidCur == TokKind.At);
            Contracts.AssertValueOrNull(sourceRestriction);

            Token curlyClose;

            var      commas                = new List <Token>();
            var      colons                = new List <Token>();
            var      ids                   = new List <Identifier>();
            var      exprs                 = new List <TexlNode>();
            var      sourceList            = new List <ITexlSource>();
            TexlNode sourceRestrictionNode = null;

            Token primaryToken = _curs.TokMove();

            if (primaryToken.Kind == TokKind.At)
            {
                Contracts.AssertValue(sourceRestriction);
                sourceList.Add(sourceRestrictionTrivia);
                sourceList.Add(new TokenSource(primaryToken));
                sourceList.Add(ParseTrivia());

                primaryToken          = sourceRestriction.Token;
                sourceRestrictionNode = new FirstNameNode(ref _idNext, sourceRestriction.Token, sourceRestriction);

                if (_curs.TidCur != TokKind.CurlyOpen)
                {
                    ErrorTid(_curs.TokCur, TokKind.CurlyOpen);
                    curlyClose = TokEat(TokKind.CurlyClose);
                    return(new RecordNode(
                               ref _idNext,
                               sourceRestriction.Token,
                               new SourceList(
                                   new SpreadSource(sourceList),
                                   curlyClose != null ? (ITexlSource) new TokenSource(curlyClose) : new SpreadSource()),
                               ids.ToArray(),
                               exprs.ToArray(),
                               null,
                               null,
                               curlyClose,
                               sourceRestrictionNode));
                }

                sourceList.Add(new TokenSource(_curs.TokMove()));
                sourceList.Add(ParseTrivia());
            }
            else
            {
                sourceList.Add(new TokenSource(primaryToken));
                sourceList.Add(ParseTrivia());
            }

            while (_curs.TidCur != TokKind.CurlyClose)
            {
                // id
                Identifier ident = ParseIdentifier();
                sourceList.Add(new IdentifierSource(ident));
                sourceList.Add(ParseTrivia());

                // :
                if (_curs.TidCur != TokKind.Colon)
                {
                    ErrorTid(_curs.TokCur, TokKind.Colon);
                    var      errorToken = _curs.TokMove();
                    TexlNode errorExp   = CreateError(errorToken, TexlStrings.ErrColonExpected);
                    sourceList.Add(new TokenSource(errorToken));
                    sourceList.Add(ParseTrivia());
                    ids.Add(ident);
                    exprs.Add(errorExp);
                    break;
                }
                var colon = _curs.TokMove();
                colons.Add(colon);
                sourceList.Add(new TokenSource(colon));
                sourceList.Add(ParseTrivia());

                // expr
                // SingleExpr here means we don't want chains, but individual expressions.
                TexlNode expr = ParseExpr(Precedence.SingleExpr);

                ids.Add(ident);
                exprs.Add(expr);
                sourceList.Add(new NodeSource(expr));
                sourceList.Add(ParseTrivia());

                // ,
                if (_curs.TidCur != TokKind.Comma)
                {
                    break;
                }

                var comma = _curs.TokMove();
                commas.Add(comma);
                sourceList.Add(new TokenSource(comma));
                sourceList.Add(ParseTrivia());

                if (_curs.TidCur == TokKind.CurlyClose)
                {
                    TexlNode errorExp = CreateError(comma, TexlStrings.ErrColonExpected);
                    exprs.Add(errorExp);
                    ids.Add(ParseIdentifier());
                }
            }

            Contracts.Assert(ids.Count == exprs.Count);

            Token[] commaArray = (commas != null) ? commas.ToArray() : null;
            Token[] colonArray = (colons != null) ? colons.ToArray() : null;

            curlyClose = TokEat(TokKind.CurlyClose);
            if (curlyClose != null)
            {
                sourceList.Add(new TokenSource(curlyClose));
            }

            return(new RecordNode(
                       ref _idNext,
                       primaryToken,
                       new SourceList(sourceList),
                       ids.ToArray(),
                       exprs.ToArray(),
                       commaArray,
                       colonArray,
                       curlyClose,
                       sourceRestrictionNode));
        }
Exemple #21
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);
        }
Exemple #22
0
 public override Result Visit(FirstNameNode node, Context context)
 {
     return(Default);
 }
Exemple #23
0
 public abstract void Visit(FirstNameNode node);
 public override void Visit(FirstNameNode node)
 {
 }
Exemple #25
0
 public override void Visit(FirstNameNode node)
 {
     SetCurrentNodeAsResult(node);
 }