internal FieldDeclarationSyntax ParseField(
            IClassDeclarationSyntax declaringType,
            bool mutableBinding,
            ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            // We should only be called when there is a binding keyword
            var  binding    = Tokens.Required <IBindingToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;

            Tokens.Expect <IColonToken>();
            var type = ParseType();
            IExpressionSyntax?initializer = null;

            if (Tokens.Accept <IEqualsToken>())
            {
                initializer = ParseExpression();
            }

            var semicolon = Tokens.Expect <ISemicolonToken>();
            var span      = TextSpan.Covering(binding, semicolon);

            return(new FieldDeclarationSyntax(declaringType, span, File, accessModifer, mutableBinding,
                                              identifier.Span, name, type, initializer));
        }
        internal IMemberDeclarationSyntax ParseMemberFunction(
            IClassDeclarationSyntax declaringType,
            ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            var  fn         = Tokens.Expect <IFunctionKeywordToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;
            var  bodyParser = BodyParser();
            var  parameters = bodyParser.ParseParameters(bodyParser.ParseMethodParameter);

            var(returnType, reachabilityAnnotations) = ParseReturn();

            var selfParameter   = parameters.OfType <ISelfParameterSyntax>().FirstOrDefault();
            var namedParameters = parameters.Except(parameters.OfType <ISelfParameterSyntax>())
                                  .Cast <INamedParameterSyntax>().ToFixedList();

            // if no self parameter, it is an associated function
            if (selfParameter is null)
            {
                var body = bodyParser.ParseFunctionBody();
                var span = TextSpan.Covering(fn, body.Span);
                return(new AssociatedFunctionDeclarationSyntax(declaringType, span, File, accessModifer, identifier.Span, name, namedParameters, returnType, reachabilityAnnotations, body));
            }

            if (!(parameters[0] is ISelfParameterSyntax))
            {
                Add(ParseError.SelfParameterMustBeFirst(File, selfParameter.Span));
            }

            foreach (var extraSelfParameter in parameters.OfType <ISelfParameterSyntax>().Skip(1))
            {
                Add(ParseError.ExtraSelfParameter(File, extraSelfParameter.Span));
            }

            // It is a method that may or may not have a body
            if (Tokens.Current is IOpenBraceToken)
            {
                var body = bodyParser.ParseFunctionBody();
                var span = TextSpan.Covering(fn, body.Span);
                return(new ConcreteMethodDeclarationSyntax(declaringType, span, File, accessModifer,
                                                           identifier.Span, name, selfParameter, namedParameters, returnType, reachabilityAnnotations, body));
            }
            else
            {
                var semicolon = bodyParser.Tokens.Expect <ISemicolonToken>();
                var span      = TextSpan.Covering(fn, semicolon);
                return(new AbstractMethodDeclarationSyntax(declaringType, span, File, accessModifer,
                                                           identifier.Span, name, selfParameter, namedParameters, returnType, reachabilityAnnotations));
            }
        }
        private IClassDeclarationSyntax ParseClass(
            ModifierParser modifiers)
        {
            var accessModifier  = modifiers.ParseAccessModifier();
            var mutableModifier = modifiers.ParseMutableModifier();

            modifiers.ParseEndOfModifiers();
            var  @class     = Tokens.Expect <IClassKeywordToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;
            var  headerSpan = TextSpan.Covering(@class, identifier.Span);
            var  bodyParser = BodyParser();

            return(new ClassDeclarationSyntax(ContainingNamespace, headerSpan, File, accessModifier, mutableModifier, identifier.Span,
                                              name, bodyParser.ParseClassBody));
        }
        internal NamespaceDeclarationSyntax ParseNamespaceDeclaration(
            ModifierParser modifiers)
        {
            modifiers.ParseEndOfModifiers();
            var ns = Tokens.Expect <INamespaceKeywordToken>();
            var globalQualifier = Tokens.AcceptToken <IColonColonDotToken>();

            var(name, nameSpan) = ParseNamespaceName();
            nameSpan            = TextSpan.Covering(nameSpan, globalQualifier?.Span);
            Tokens.Expect <IOpenBraceToken>();
            var bodyParser      = NamespaceBodyParser(name);
            var usingDirectives = bodyParser.ParseUsingDirectives();
            var declarations    = bodyParser.ParseNonMemberDeclarations <ICloseBraceToken>();
            var closeBrace      = Tokens.Expect <ICloseBraceToken>();
            var span            = TextSpan.Covering(ns, closeBrace);

            return(new NamespaceDeclarationSyntax(ContainingNamespace, span, File, globalQualifier != null, name, nameSpan, usingDirectives, declarations));
        }
        internal IFunctionDeclarationSyntax ParseFunction(ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            var  fn         = Tokens.Expect <IFunctionKeywordToken>();
            var  identifier = Tokens.RequiredToken <IIdentifierToken>();
            Name name       = identifier.Value;
            var  bodyParser = BodyParser();
            var  parameters = bodyParser.ParseParameters(bodyParser.ParseFunctionParameter);

            var(returnType, reachabilityAnnotations) = ParseReturn();
            var body = bodyParser.ParseFunctionBody();
            var span = TextSpan.Covering(fn, body.Span);

            return(new FunctionDeclarationSyntax(ContainingNamespace, span, File, accessModifer, identifier.Span,
                                                 name, parameters, returnType, reachabilityAnnotations, body));
        }
        internal ConstructorDeclarationSyntax ParseConstructor(
            IClassDeclarationSyntax declaringType,
            ModifierParser modifiers)
        {
            var accessModifer = modifiers.ParseAccessModifier();

            modifiers.ParseEndOfModifiers();
            var  newKeywordSpan = Tokens.Expect <INewKeywordToken>();
            var  identifier     = Tokens.AcceptToken <IIdentifierToken>();
            Name?name           = identifier is null ? null : (Name)identifier.Value;
            var  bodyParser     = BodyParser();
            // Implicit self parameter is taken to be after the current token which is expected to be `(`
            var selfParameter = new SelfParameterSyntax(Tokens.Current.Span.AtEnd(), true);
            var parameters    = bodyParser.ParseParameters(bodyParser.ParseConstructorParameter);
            var body          = bodyParser.ParseFunctionBody();
            // For now, just say constructors have no annotations
            var reachabilityAnnotations = new ReachabilityAnnotationsSyntax(Tokens.Current.Span.AtStart(), null, null);
            var span = TextSpan.Covering(newKeywordSpan, body.Span);

            return(new ConstructorDeclarationSyntax(declaringType, span, File, accessModifer,
                                                    TextSpan.Covering(newKeywordSpan, identifier?.Span), name, selfParameter, parameters, reachabilityAnnotations, body));
        }