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)); }