Beispiel #1
0
        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));
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
            }
            }
        }
Beispiel #5
0
        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));
        }
Beispiel #9
0
        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));
        }
Beispiel #10
0
        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);
            }
        }
Beispiel #11
0
        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));
        }