public JSXElement(JSXOpeningElement opening, INode[] children, JSXClosingElement closing, Location sourceLocation) : base(NodeType.JSXElement, sourceLocation) { this.OpeningElement = opening; this.Children = children; this.ClosingElement = closing; }
// Parses entire JSX element, including it's opening tag // (starting after '<'), attributes, contents and closing tag. private JSXElement ParseJSXElementAt(Position startPos) { var opening = this.ParseJSXOpeningElementAt(startPos); JSXClosingElement closing = null; var children = new List <INode>(); if (!opening.SelfClosing) { while (true) { switch (_scaner.Token.Type) { case TokenType.JSXTagStart: startPos = _scaner.Token.SourceLocation.Start; _scaner.Next(); if (_scaner.Eat(TokenType.Slash)) { closing = this.ParseJSXClosingElementAt(startPos); goto OutsideWhile; } children.Add(this.ParseJSXElementAt(startPos)); break; case TokenType.JSXText: children.Add(this.ParseExprAtom()); break; case TokenType.BraceLeft: children.Add(this.ParseJSXExpressionContainer()); break; default: _scaner.Unexpected(); break; } } OutsideWhile: if (this.GetQualifiedJSXName(closing.Name) != this.GetQualifiedJSXName(opening.Name)) { _scaner.Raise( string.Format( "Expected corresponding JSX closing tag for <{0}>", this.GetQualifiedJSXName(opening.Name) ) ); } } if (_scaner.Token.Type == TokenType.Relational && _scaner.Token.Value == "<") { _scaner.Raise("Adjacent JSX elements must be wrapped in an enclosing tag"); } return(new JSXElement(opening, children.ToArray(), closing, new Location(startPos, _scaner.CurrentPosition()))); }