예제 #1
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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)));
 }