/// <summary> /// Makes the node. /// </summary> /// <param name="tokenStream">The token queue.</param> /// <returns>SyntaxNode.</returns> public SyntaxNode MakeNode(TokenStream tokenStream) { // a root fragment must be in the form of keywords: fragment on TargetType{} // "fragment" keyword var startLocation = tokenStream.Location; tokenStream.MatchOrThrow(KEYWORDS.Fragment); tokenStream.Next(); // name of the fragment tokenStream.MatchOrThrow <NameToken>(); var fragmentName = tokenStream.ActiveToken.Text; tokenStream.Next(); // "on" keyword var targetType = ReadOnlyMemory <char> .Empty; if (tokenStream.Match(KEYWORDS.On)) { tokenStream.Next(); // target type tokenStream.MatchOrThrow <NameToken>(); targetType = tokenStream.ActiveToken.Text; tokenStream.Next(); } // account for possible directives on this field var directives = new List <SyntaxNode>(); while (tokenStream.Match(TokenType.AtSymbol)) { var dirMaker = NodeMakerFactory.CreateMaker <DirectiveNode>(); var directive = dirMaker.MakeNode(tokenStream); directives.Add(directive); } // must be pointing at the fragment field set now tokenStream.MatchOrThrow(TokenType.CurlyBraceLeft); var fieldCollectionMaker = NodeMakerFactory.CreateMaker <FieldCollectionNode>(); var collection = fieldCollectionMaker.MakeNode(tokenStream); var node = new NamedFragmentNode(startLocation, fragmentName, targetType); if (collection.Children.Count > 0) { node.AddChild(collection); } foreach (var directive in directives) { node.AddChild(directive); } return(node); }
/// <summary> /// Processes the queue as far as it needs to to generate a fully qualiffied /// <see cref="SyntaxNode" /> based on its ruleset. /// </summary> /// <param name="tokenStream">The token stream.</param> /// <returns>LexicalToken.</returns> public SyntaxNode MakeNode(TokenStream tokenStream) { var directives = new List <SyntaxNode>(); SyntaxNode variableCollection = null; SyntaxNode fieldCollection = null; // check to see if this is qualified operation root // default to "query" as per the specification if not tokenStream.Prime(); var operationTypeNode = this.CreateNode(tokenStream); // a variable collection will begin with an open paren if (tokenStream.Match(TokenType.ParenLeft)) { var variableMaker = NodeMakerFactory.CreateMaker <VariableCollectionNode>(); variableCollection = variableMaker.MakeNode(tokenStream); } // account for possible directives on this operation while (tokenStream.Match(TokenType.AtSymbol)) { var dirMaker = NodeMakerFactory.CreateMaker <DirectiveNode>(); var directive = dirMaker.MakeNode(tokenStream); directives.Add(directive); } // only thing left on the operaton root is the field selection tokenStream.MatchOrThrow(TokenType.CurlyBraceLeft); var maker = NodeMakerFactory.CreateMaker <FieldCollectionNode>(); fieldCollection = maker.MakeNode(tokenStream); if (variableCollection != null) { operationTypeNode.AddChild(variableCollection); } foreach (var directive in directives) { operationTypeNode.AddChild(directive); } if (fieldCollection != null && fieldCollection.Children.Any()) { operationTypeNode.AddChild(fieldCollection); } return(operationTypeNode); }
/// <summary> /// Processes the queue as far as it needs to to generate a fully qualiffied /// <see cref="SyntaxNode" /> based on its ruleset. /// </summary> /// <param name="tokenStream">The token stream.</param> /// <returns>LexicalToken.</returns> public SyntaxNode MakeNode(TokenStream tokenStream) { // the token stream MUST be positioned at an open paren for this maker to function correclty tokenStream.MatchOrThrow(TokenType.ParenLeft); var collection = new VariableCollectionNode(tokenStream.Location); tokenStream.Next(); var variableMaker = NodeMakerFactory.CreateMaker <VariableNode>(); while (!tokenStream.EndOfStream && !tokenStream.Match(TokenType.ParenRight)) { var variable = variableMaker.MakeNode(tokenStream); collection.AddChild(variable); } // ensure and move past the close paren tokenStream.MatchOrThrow(TokenType.ParenRight); tokenStream.Next(); return(collection); }
/// <summary> /// Processes the queue as far as it needs to to generate a fully qualiffied /// <see cref="SyntaxNode" /> based on its ruleset. /// </summary> /// <param name="tokenStream">The token stream.</param> /// <returns>LexicalToken.</returns> public SyntaxNode MakeNode(TokenStream tokenStream) { // ensure we're pointing at a potential input item tokenStream.MatchOrThrow <NameToken>(); var startLocation = tokenStream.Location; var directives = new List <SyntaxNode>(); var name = tokenStream.ActiveToken.Text; tokenStream.Next(); // input values are in the format: NameToken: ValueToken // ensure and consume the colon tokenStream.MatchOrThrow(TokenType.Colon); tokenStream.Next(); var maker = NodeMakerFactory.CreateMaker <InputValueNode>(); var value = maker.MakeNode(tokenStream); // account for possible directives on this field while (tokenStream.Match(TokenType.AtSymbol)) { var dirMaker = NodeMakerFactory.CreateMaker <DirectiveNode>(); var directive = dirMaker.MakeNode(tokenStream); directives.Add(directive); } var node = new InputItemNode(startLocation, name); node.AddChild(value); foreach (var directive in directives) { node.AddChild(directive); } return(node); }
/// <summary> /// Processes the queue as far as it needs to to generate a fully qualiffied /// <see cref="SyntaxNode" /> based on its ruleset. /// </summary> /// <param name="tokenStream">The token stream.</param> /// <returns>LexicalToken.</returns> public SyntaxNode MakeNode(TokenStream tokenStream) { // extracts a variable in the format of: $name: declaredType [= defaultValue] // the token stream MUST be positioned at a dollar sign for this maker to function correclty tokenStream.MatchOrThrow(TokenType.Dollar); var startLocation = tokenStream.Location; tokenStream.Next(); // must be a name token tokenStream.MatchOrThrow <NameToken>(); var variableName = tokenStream.ActiveToken.Text; tokenStream.Next(); // must be a colon tokenStream.MatchOrThrow(TokenType.Colon); tokenStream.Next(); // extract the type expression while the tokens are of characters '[', ']', '!', {NameToken} LexicalToken startToken = null; LexicalToken endToken = null; while ( tokenStream.Match(TokenType.BracketLeft) || tokenStream.Match(TokenType.BracketRight) || tokenStream.Match(TokenType.Bang) || tokenStream.Match(TokenType.Name)) { startToken = startToken ?? tokenStream.ActiveToken; endToken = tokenStream.ActiveToken; tokenStream.Next(); } var typeExpression = ReadOnlyMemory <char> .Empty; if (startToken != null) { typeExpression = tokenStream.SourceText.Slice( startToken.Location.AbsoluteIndex, endToken.Location.AbsoluteIndex + endToken.Text.Length - startToken.Location.AbsoluteIndex); } // could be an equal sign for a default value SyntaxNode defaultValue = null; if (tokenStream.Match(TokenType.EqualsSign)) { tokenStream.Next(); var maker = NodeMakerFactory.CreateMaker <InputValueNode>(); defaultValue = maker.MakeNode(tokenStream); } var variable = new VariableNode(startLocation, variableName, typeExpression); if (defaultValue != null) { variable.AddChild(defaultValue); } return(variable); }
/// <summary> /// Creates the maker. /// </summary> /// <typeparam name="TSyntaxNodeType">The type of the t syntax node type.</typeparam> /// <returns>ISyntaxNodeMaker.</returns> public static ISyntaxNodeMaker CreateMaker <TSyntaxNodeType>() { return(NodeMakerFactory.CreateMaker(typeof(TSyntaxNodeType))); }