private EnumVariantSyntax ParseEnumVariant() { var identifier = Tokens.RequiredToken <IIdentifierToken>(); // TODO we actually expect commas separating them, need to improve this var comma = Tokens.AcceptToken <ICommaToken>(); return(new EnumVariantSyntax(identifier.Value)); }
private ITypeSyntax ParseTypeWithCapability <TCapabilityToken>(ReferenceCapability immutableCapability, ReferenceCapability mutableCapability) where TCapabilityToken : ICapabilityToken { var primaryCapability = Tokens.RequiredToken <TCapabilityToken>(); var mutableKeyword = Tokens.AcceptToken <IMutableKeywordToken>(); var referent = ParseBareType(); var span = TextSpan.Covering(primaryCapability.Span, referent.Span); var capability = mutableKeyword is null ? immutableCapability : mutableCapability; return(new CapabilityTypeSyntax(capability, referent, span)); }
private AccessModifier?AcceptFieldGetter() { // TODO allow other access modifiers var publicKeyword = Tokens.AcceptToken <IPublicKeywordToken>(); var getKeyword = Tokens.AcceptToken <IGetKeywordToken>(); if (publicKeyword == null && getKeyword == null) { return(null); } return(AccessModifier.Public); }
public ParameterSyntax ParseParameter() { switch (Tokens.Current) { case IRefKeywordToken _: case IMutableKeywordToken _: case ISelfKeywordToken _: { var span = Tokens.Current.Span; var refSelf = Tokens.Accept <IRefKeywordToken>(); var mutableSelf = Tokens.Accept <IMutableKeywordToken>(); var selfSpan = Tokens.Expect <ISelfKeywordToken>(); span = TextSpan.Covering(span, selfSpan); var name = nameContext.Qualify(SpecialName.Self); return(new SelfParameterSyntax(span, name, refSelf, mutableSelf)); } case IDotToken _: { var dot = Tokens.Expect <IDotToken>(); var identifier = Tokens.RequiredToken <IIdentifierToken>(); var equals = Tokens.AcceptToken <IEqualsToken>(); ExpressionSyntax defaultValue = null; if (equals != null) { defaultValue = ParseExpression(); } var span = TextSpan.Covering(dot, identifier.Span, defaultValue?.Span); var name = nameContext.Qualify(SimpleName.Special("field_" + identifier.Value)); return(new FieldParameterSyntax(span, name, defaultValue)); } default: { var span = Tokens.Current.Span; var isParams = Tokens.Accept <IParamsKeywordToken>(); var mutableBinding = Tokens.Accept <IVarKeywordToken>(); var identifier = Tokens.RequiredToken <IIdentifierOrUnderscoreToken>(); var name = nameContext.Qualify(variableNumbers.VariableName(identifier.Value)); Tokens.Expect <IColonToken>(); // Need to not consume the assignment that separates the type from the default value, // hence the min operator precedence. var type = ParseExpression(OperatorPrecedence.AboveAssignment); ExpressionSyntax defaultValue = null; if (Tokens.Accept <IEqualsToken>()) { defaultValue = ParseExpression(); } span = TextSpan.Covering(span, type.Span, defaultValue?.Span); return(new NamedParameterSyntax(span, isParams, mutableBinding, name, type, defaultValue)); } } }
public ITypeSyntax ParseType() { var typeSyntax = ParseTypeWithCapability(); IQuestionToken?question; while ((question = Tokens.AcceptToken <IQuestionToken>()) != null) { var span = TextSpan.Covering(typeSyntax.Span, question.Span); return(new OptionalTypeSyntax(span, typeSyntax)); } return(typeSyntax); }
public UsingDirectiveSyntax AcceptUsingDirective() { if (!Tokens.Accept <IUsingKeywordToken>()) { return(null); } var identifiers = AcceptOneOrMore <IIdentifierToken, IDotToken>( () => Tokens.AcceptToken <IIdentifierToken>()); RootName name = GlobalNamespaceName.Instance; foreach (var identifier in identifiers) { name = name.Qualify(identifier.Value); } Tokens.Expect <ISemicolonToken>(); return(new UsingDirectiveSyntax((Name)name)); }
public GenericParameterSyntax ParseGenericParameter() { Name name; var dollar = Tokens.AcceptToken <IDollarToken>(); if (dollar != null) { var lifetime = Tokens.RequiredToken <ILifetimeNameToken>(); var span = TextSpan.Covering(dollar.Span, lifetime.Span); switch (lifetime) { case IIdentifierToken lifetimeIdentifier: name = nameContext.Qualify(lifetimeIdentifier.Value); break; case IRefKeywordToken _: name = nameContext.Qualify(SpecialName.Ref); break; case IOwnedKeywordToken _: Add(ParseError.OwnedNotValidAsGenericLifetimeParameter(File, span)); // We just treat it as if they had written `$\owned` name = nameContext.Qualify("owned"); break; default: throw NonExhaustiveMatchException.For(lifetime); } return(new GenericParameterSyntax(true, false, name, null)); } var isParams = Tokens.Accept <IParamsKeywordToken>(); var identifier = Tokens.RequiredToken <IIdentifierToken>(); name = nameContext.Qualify(identifier.Value); ExpressionSyntax typeExpression = null; if (Tokens.Accept <IColonToken>()) { typeExpression = ParseExpression(); } return(new GenericParameterSyntax(false, isParams, name, typeExpression)); }
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)); }
public NamespaceDeclarationSyntax ParseNamespaceDeclaration( FixedList <AttributeSyntax> attributes, FixedList <IModiferToken> modifiers) { // TODO generate errors for attributes or modifiers Tokens.Expect <INamespaceKeywordToken>(); var globalQualifier = Tokens.AcceptToken <IColonColonToken>(); var(name, span) = ParseNamespaceName(); span = TextSpan.Covering(span, globalQualifier?.Span); Tokens.Expect <IOpenBraceToken>(); var bodyParser = NestedParser(nameContext.Qualify(name)); var usingDirectives = bodyParser.ParseUsingDirectives(); var declarations = bodyParser.ParseDeclarations(); Tokens.Expect <ICloseBraceToken>(); return(new NamespaceDeclarationSyntax(File, globalQualifier != null, name, span, nameContext, usingDirectives, declarations)); }
private (ITypeSyntax?Type, bool InferMutableType) ParseVariableDeclarationType() { var mutableKeyword = Tokens.AcceptToken <IMutableKeywordToken>(); if (mutableKeyword is null) { return(ParseType(), false); } switch (Tokens.Current) { case IEqualsToken _: case ISemicolonToken _: return(null, true); default: return(ParseMutableType(mutableKeyword), false); } }
public InitializerDeclarationSyntax ParseInitializer( FixedList <AttributeSyntax> attributes, FixedList <IModiferToken> modifiers) { var initKeywordSpan = Tokens.Expect <IInitKeywordToken>(); var identifier = Tokens.AcceptToken <IIdentifierToken>(); var name = nameContext.Qualify(SimpleName.Special("init" + (identifier != null ? "_" + identifier.Value : ""))); var bodyParser = NestedParser(name); var genericParameters = AcceptGenericParameters(); var parameters = bodyParser.ParseParameters(); var genericConstraints = ParseGenericConstraints(); var mayEffects = ParseMayEffects(); var noEffects = ParseNoEffects(); var(requires, ensures) = ParseFunctionContracts(); var body = bodyParser.ParseBlock(); return(new InitializerDeclarationSyntax(File, modifiers, name, TextSpan.Covering(initKeywordSpan, identifier?.Span), genericParameters, parameters, genericConstraints, mayEffects, noEffects, requires, ensures, 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)); }
public IConstructorParameterSyntax ParseConstructorParameter() { switch (Tokens.Current) { case IDotToken _: { var dot = Tokens.Expect <IDotToken>(); var identifier = Tokens.RequiredToken <IIdentifierToken>(); var equals = Tokens.AcceptToken <IEqualsToken>(); IExpressionSyntax?defaultValue = null; if (equals != null) { defaultValue = ParseExpression(); } var span = TextSpan.Covering(dot, identifier.Span, defaultValue?.Span); Name name = identifier.Value; return(new FieldParameterSyntax(span, name, defaultValue)); } default: return(ParseFunctionParameter()); } }
public IUsingDirectiveSyntax?AcceptUsingDirective() { var accept = Tokens.AcceptToken <IUsingKeywordToken>(); if (accept is null) { return(null); } var identifiers = ParseManySeparated <(IIdentifierToken?, TextSpan), IDotToken>( () => Tokens.ExpectToken <IIdentifierToken>()); NamespaceName name = NamespaceName.Global; foreach (var(identifier, _) in identifiers) { if (!(identifier is null)) { name = name.Qualify(identifier.Value); } } var semicolon = Tokens.Expect <ISemicolonToken>(); var span = TextSpan.Covering(accept.Span, semicolon); return(new UsingDirectiveSyntax(span, name)); }