private static IEnumerable <GenericParameterNode> ParseGenericParameters(CrawlParser.Generic_parametersContext genericsContext)
 {
     for (int i = 1; i < genericsContext.ChildCount; i += 2)
     {
         yield return(ParseGenericParameter((CrawlParser.GenericContext)genericsContext.GetChild(i)));
     }
 }
        private static DeclerationNode ParseClassDecleration(RuleContext classPart, ProtectionLevel protectionLevel, Interval interval)
        {
            //The second last child. And one for the zero-indexing.
            int genericParametersIndex = classPart.ChildCount - 2 - 1;

            ITerminalNode tn1 = (ITerminalNode)classPart.GetChild(0);

            ITerminalNode tn2 = (ITerminalNode)classPart.GetChild(1);

            CrawlParser.InheritancesContext baseTypes = classPart.GetChild(2) as CrawlParser.InheritancesContext;

            IEnumerable <IdentifierNode> inheritances = baseTypes == null ? new List <IdentifierNode>() : ParseInheritances(baseTypes);

            CrawlParser.Generic_parametersContext genericParametersContext =
                classPart.GetChild(genericParametersIndex) as CrawlParser.Generic_parametersContext;

            RuleContext body = (RuleContext)classPart.LastChild();

            List <GenericParameterNode> genericParameters = new List <GenericParameterNode>();

            if (genericParametersContext != null)
            {
                genericParameters.AddRange(ParseGenericParameters(genericParametersContext));
            }

            if (tn1.Symbol.Type != CrawlLexer.CLASS)
            {
                throw new CrawlImpossibleStateException("Trying to parse a class that is not a class", interval);
            }

            BlockNode bodyBlock = ParseBlockNode(body);

            return(CrawlSyntaxNode.ClassTypeDecleration(interval, protectionLevel, null, ParseIdentifier(tn2), inheritances, genericParameters, bodyBlock));
        }
        private static DeclerationNode ParseMethodDecleration(RuleContext methodContext, ProtectionLevel protectionLevel, Interval interval)
        {
            //Return Type
            TypeNode returnType =
                ParseType((CrawlParser.TypeContext)methodContext.GetChild(0));

            //Parameters TODO: Use parameter names.
            List <ParameterNode> parameters =
                ParseParameters((CrawlParser.ParametersContext)methodContext.GetChild(1));

            TypeNode methodSignature = GenerateMethodSignature(returnType, parameters.Select(foo => foo.ParameterType).ToList());

            //Generic Parameters
            List <GenericParameterNode> genericParameters
                = new List <GenericParameterNode>();


            CrawlParser.Generic_parametersContext genericsContext =
                methodContext.GetChild(2) as CrawlParser.Generic_parametersContext;

            if (genericsContext != null)
            {
                genericParameters.AddRange(ParseGenericParameters(genericsContext));
            }

            //Body
            RuleContext bodyContext = (RuleContext)methodContext.LastChild().GetChild(1);
            BlockNode   body        = ParseBlockNode(bodyContext);

            //Identifier
            int           identifierIndex    = methodContext.ChildCount - 2 - 1; //Identifier is always second last. And then one for the zero-indexed arrays.
            ITerminalNode identifierTerminal =
                (ITerminalNode)methodContext.GetChild(identifierIndex);
            IdentifierNode identifier = ParseIdentifier(identifierTerminal);

            //Combine it all.
            return(CrawlSyntaxNode.MethodDecleration(
                       interval,
                       protectionLevel,
                       null, /*scope has no stuff yet*/
                       methodSignature,
                       parameters,
                       body,
                       identifier,
                       genericParameters
                       ));
        }