示例#1
0
        public override Span GetCompleteSpan()
        {
            int      min      = Token.Span.Min;
            TexlNode leftNode = Left;

            while (leftNode != null)
            {
                DottedNameNode dottedLeft;
                if ((dottedLeft = leftNode.AsDottedName()) != null)
                {
                    leftNode = dottedLeft.Left;
                }
                else
                {
                    min = leftNode.GetCompleteSpan().Min;
                    break;
                }
            }
            return(new Span(min, Right.VerifyValue().Token.VerifyValue().Span.Lim));
        }
示例#2
0
        public CallNode(ref int idNext, Token primaryToken, SourceList sourceList, Identifier head, TexlNode headNode, ListNode args, Token tokParenClose)
            : base(ref idNext, primaryToken, sourceList)
        {
            Contracts.AssertValue(head);
            Contracts.AssertValueOrNull(headNode);
            Contracts.AssertValue(args);
            Contracts.AssertValueOrNull(tokParenClose);

            Head        = head;
            HeadNode    = headNode;
            Args        = args;
            Args.Parent = this;
            ParenClose  = tokParenClose;

            int headDepth = HeadNode == null ? 0 : HeadNode.Depth;

            _depth = 1 + (args.Depth > headDepth ? args.Depth : headDepth);

            if (headNode != null)
            {
                MinChildID = Math.Min(headNode.MinChildID, MinChildID);
            }

            if (args != null)
            {
                MinChildID = Math.Min(args.MinChildID, MinChildID);
            }

#pragma warning disable 420
            // A volatile field should not normally be passed using a ref or out parameter, since it will not be treated
            // as volatile within the scope of the function. There are exceptions to this, such as when calling an interlocked API.
            // Hence disabling the warning for this instance.
            int invocationId = Interlocked.Increment(ref _uniqueInvocationIdNext);
#pragma warning restore 420

            // We need to generate a globally unique name for this function invocation, so we use
            // a new (hardcoded) guid as well as the unique counter to avoid colliding with any
            // other data sources that may be imported by the user.
            UniqueInvocationId = string.Format("Inv_7339A45FDB3141D49CB36063B712F5E0_{0}", invocationId);
        }
示例#3
0
        // Assumes ownership of all of the array args.
        public RecordNode(ref int idNext, Token primaryTokens, SourceList sourceList, Identifier[] ids, TexlNode[] exprs, Token[] commas, Token[] colons, Token curlyCloseToken, TexlNode sourceRestriction = null)
            : base(ref idNext, primaryTokens, sourceList, exprs)
        {
            Contracts.AssertValue(ids);
            Contracts.AssertValue(exprs);
            Contracts.Assert(ids.Length == exprs.Length);
            Contracts.AssertValueOrNull(commas);
            Contracts.AssertValueOrNull(colons);
            Contracts.AssertValueOrNull(curlyCloseToken);
            Contracts.AssertValueOrNull(sourceRestriction);

            Ids               = ids;
            Commas            = commas;
            Colons            = colons;
            CurlyClose        = curlyCloseToken;
            SourceRestriction = sourceRestriction;
            if (sourceRestriction != null)
            {
                sourceRestriction.Parent = this;
                MinChildID = Math.Min(sourceRestriction.MinChildID, MinChildID);
            }
        }
示例#4
0
        public DottedNameNode(ref int idNext, Token primaryToken, SourceList sourceList, TexlNode left, Identifier right, TexlNode rightNode)
            : base(ref idNext, primaryToken, sourceList)
        {
            Contracts.AssertValue(primaryToken);
            Contracts.Assert(primaryToken.IsDottedNamePunctuator);
            Contracts.AssertValue(left);
            Contracts.AssertValue(right);

            // The LHS of a [] can only be a first name node. E.g. foo[bar] is valid, but foo!bar[car] is not.
            // Also, dotted names can't mix tokens, except for []. E.g. foo[bar]!car is valid, but foo.bar!car is not.
            Contracts.Assert(primaryToken.Kind == TokKind.BracketOpen ?
                             left is FirstNameNode :
                             !(left is DottedNameNode) || left.AsDottedName().Token.Kind == TokKind.BracketOpen || left.AsDottedName().Token.Kind == primaryToken.Kind);

            Left                          = left;
            Left.Parent                   = this;
            Right                         = right;
            RightNode                     = rightNode;
            HasOnlyIdentifiers            = left is FirstNameNode || (left is DottedNameNode && left.AsDottedName().HasOnlyIdentifiers);
            HasPossibleNamespaceQualifier = HasOnlyIdentifiers || left is ParentNode || left is SelfNode;
            _depth                        = left.Depth + 1;

            MinChildID = Math.Min(left.MinChildID, rightNode?.MinChildID ?? MinChildID);
        }
示例#5
0
        public BinaryOpNode(ref int idNext, Token primaryToken, SourceList sourceList, BinaryOp op, TexlNode left, TexlNode right)
            : base(ref idNext, primaryToken, sourceList)
        {
            Contracts.AssertValue(left);
            Contracts.AssertValue(right);
            Left         = left;
            Left.Parent  = this;
            Right        = right;
            Right.Parent = this;
            Op           = op;
            _depth       = 1 + (left.Depth > right.Depth ? left.Depth : right.Depth);

            MinChildID = Math.Min(left.MinChildID, right.MinChildID);
        }
示例#6
0
 public bool InTree(TexlNode root)
 {
     Contracts.AssertValue(root);
     return(root.MinChildID <= Id && Id <= root.Id);
 }
示例#7
0
        public DPath ToDPath()
        {
            Contracts.Assert(HasPossibleNamespaceQualifier);

            Stack <DName> names = new Stack <DName>(2);

            names.Push(Right.Name);

            // Traverse the DottedNameNode structure non-recursively, to account for the possibility
            // that it may be very deep. Accumulate all encountered names onto a stack.
            DottedNameNode pointer     = this;
            bool           reachedLeft = false;

            while (pointer != null)
            {
                TexlNode left = pointer.Left;

                switch (left)
                {
                case FirstNameNode firstNameNode:
                    names.Push(firstNameNode.Ident.Name);
                    reachedLeft = true;
                    break;

                case ParentNode parentNode:
                    names.Push(new DName(TexlLexer.KeywordParent));
                    reachedLeft = true;
                    break;

                case SelfNode selfNode:
                    names.Push(new DName(TexlLexer.KeywordSelf));
                    reachedLeft = true;
                    break;
                }

                if (reachedLeft)
                {
                    break;
                }

                pointer = left as DottedNameNode;
                if (pointer != null)
                {
                    names.Push(pointer.Right.Name);
                }
                else
                {
                    Contracts.Assert(false, "Can only do this for dotted names consisting of identifiers");
                }
            }

            // For the DPath by unwinding the names stack
            DPath path = DPath.Root;

            while (names.Count > 0)
            {
                path = path.Append(names.Pop());
            }

            return(path);
        }
示例#8
0
 public UnaryOpNode(ref int idNext, Token primaryToken, SourceList sourceList, UnaryOp op, TexlNode child)
     : base(ref idNext, primaryToken, sourceList)
 {
     Contracts.AssertValue(child);
     Child        = child;
     Child.Parent = this;
     Op           = op;
     _depth       = child.Depth + 1;
     MinChildID   = Math.Min(child.MinChildID, MinChildID);
 }