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)); }
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); }
// 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); } }
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); }
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); }
public bool InTree(TexlNode root) { Contracts.AssertValue(root); return(root.MinChildID <= Id && Id <= root.Id); }
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); }
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); }