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)); }
private static INonMemberDeclaration BuildNonMemberDeclaration(INonMemberEntityDeclarationSyntax entity) { return(entity switch { IClassDeclarationSyntax syn => BuildClass(syn), IFunctionDeclarationSyntax syn => BuildFunction(syn), _ => throw ExhaustiveMatch.Failed(entity) });
private static LexicalScope BuildClassScope( IClassDeclarationSyntax @class, LexicalScope containingScope) { // Only "static" names are in scope. Other names must use `self.` var symbols = @class.Members.OfType <IAssociatedFunctionDeclarationSyntax>() .GroupBy(m => m.Name, m => m.Symbol) .ToFixedDictionary(e => (TypeName)e.Key, e => e.ToFixedSet <IPromise <Symbol> >()); return(NestedScope.Create(containingScope, symbols)); }
private static ObjectType ResolveSelfParameterType( ISelfParameterSyntax selfParameter, IClassDeclarationSyntax declaringClass) { var selfType = declaringClass.Symbol.Result.DeclaresDataType; if (selfParameter.MutableSelf) { selfType = selfType.ToConstructorSelf(); } return(selfType); }
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)); } }
protected MemberDeclarationSyntax( IClassDeclarationSyntax declaringClass, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, TextSpan nameSpan, Name?name, IPromise <Symbol> symbol) : base(span, file, name, nameSpan, symbol) { DeclaringClass = declaringClass; AccessModifier = accessModifier; }
public AbstractMethodDeclarationSyntax( IClassDeclarationSyntax declaringClass, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, TextSpan nameSpan, Name name, ISelfParameterSyntax selfParameter, FixedList <INamedParameterSyntax> parameters, ITypeSyntax?returnType, IReachabilityAnnotationsSyntax reachabilityAnnotations) : base(declaringClass, span, file, accessModifier, nameSpan, name, selfParameter, parameters, returnType, reachabilityAnnotations) { }
public FieldDeclarationSyntax( IClassDeclarationSyntax declaringClass, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, bool mutableBinding, TextSpan nameSpan, Name name, ITypeSyntax type, IExpressionSyntax?initializer) : base(declaringClass, span, file, accessModifier, nameSpan, name, new AcyclicPromise <FieldSymbol>()) { IsMutableBinding = mutableBinding; Name = name; Type = type; this.initializer = initializer; Symbol = (AcyclicPromise <FieldSymbol>)base.Symbol; }
public ConstructorDeclarationSyntax( IClassDeclarationSyntax declaringType, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, TextSpan nameSpan, Name?name, ISelfParameterSyntax implicitSelfParameter, FixedList <IConstructorParameterSyntax> parameters, IReachabilityAnnotationsSyntax reachabilityAnnotations, IBodySyntax body) : base(span, file, accessModifier, nameSpan, name, parameters, reachabilityAnnotations, new AcyclicPromise <ConstructorSymbol>()) { DeclaringClass = declaringType; ImplicitSelfParameter = implicitSelfParameter; Parameters = parameters; Body = body; Symbol = (AcyclicPromise <ConstructorSymbol>)base.Symbol; }
protected MethodDeclarationSyntax( IClassDeclarationSyntax declaringClass, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, TextSpan nameSpan, Name name, ISelfParameterSyntax selfParameter, FixedList <INamedParameterSyntax> parameters, ITypeSyntax?returnType, IReachabilityAnnotationsSyntax reachabilityAnnotations) : base(span, file, accessModifier, nameSpan, name, parameters, reachabilityAnnotations, new AcyclicPromise <MethodSymbol>()) { DeclaringClass = declaringClass; Name = name; SelfParameter = selfParameter; Parameters = parameters; ReturnType = returnType; Symbol = (AcyclicPromise <MethodSymbol>)base.Symbol; }
public AssociatedFunctionDeclarationSyntax( IClassDeclarationSyntax declaringClass, TextSpan span, CodeFile file, IAccessModifierToken?accessModifier, TextSpan nameSpan, Name name, FixedList <INamedParameterSyntax> parameters, ITypeSyntax?returnTypeSyntax, IReachabilityAnnotationsSyntax reachabilityAnnotations, IBodySyntax body) : base(span, file, accessModifier, nameSpan, name, parameters, reachabilityAnnotations, new AcyclicPromise <FunctionSymbol>()) { DeclaringClass = declaringClass; Name = name; Parameters = parameters; ReturnType = returnTypeSyntax; Body = body; Symbol = (AcyclicPromise <FunctionSymbol>)base.Symbol; }
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)); }
private void BuildClassSymbol(IClassDeclarationSyntax @class) { if ([email protected](AddCircularDefinitionError)) { return; } bool mutable = !(@class.MutableModifier is null); var classType = new ObjectType(@class.ContainingNamespaceName, @class.Name, mutable, ReferenceCapability.Shared); var symbol = new ObjectTypeSymbol(@class.ContainingNamespaceSymbol !, classType); @class.Symbol.Fulfill(symbol); symbolTree.Add(symbol); @class.CreateDefaultConstructor(symbolTree); void AddCircularDefinitionError() { // TODO use something better than Name here which is an old name diagnostics.Add(TypeError.CircularDefinition(@class.File, @class.NameSpan, @class)); } }
internal IMemberDeclarationSyntax ParseMemberDeclaration( IClassDeclarationSyntax classDeclaration) { var modifiers = ParseModifiers(); switch (Tokens.Current) { case IFunctionKeywordToken _: return(ParseMemberFunction(classDeclaration, modifiers)); case INewKeywordToken _: return(ParseConstructor(classDeclaration, modifiers)); case ILetKeywordToken _: return(ParseField(classDeclaration, false, modifiers)); case IVarKeywordToken _: return(ParseField(classDeclaration, true, modifiers)); default: Tokens.UnexpectedToken(); throw new ParseFailedException(); } }
public static Diagnostic CircularDefinition(CodeFile file, TextSpan span, IClassDeclarationSyntax @class) { return(new Diagnostic(file, span, DiagnosticLevel.FatalCompilationError, DiagnosticPhase.Analysis, 3006, $"Declaration of type `{@class.ContainingNamespaceName}.{@class.Name}` is part of a circular definition")); }
private FixedList <IMemberDeclarationSyntax> ParseMemberDeclarations( IClassDeclarationSyntax declaringType) { return(ParseMany <IMemberDeclarationSyntax, ICloseBraceToken>(() => ParseMemberDeclaration(declaringType))); }
private (FixedList <IMemberDeclarationSyntax> members, TextSpan span) ParseClassBody(IClassDeclarationSyntax declaringType) { var openBrace = Tokens.Expect <IOpenBraceToken>(); var members = ParseMemberDeclarations(declaringType); var closeBrace = Tokens.Expect <ICloseBraceToken>(); var span = TextSpan.Covering(openBrace, closeBrace); return(members, span); }