internal virtual TopLevelEntity Parse( TokenStream tokens, TopLevelEntity owner, FileScope fileScope) { AnnotationCollection annotations = this.parser.AnnotationParser.ParseAnnotations(tokens); ModifierCollection modifiers = ModifierCollection.Parse(tokens); string value = tokens.PeekValue(); if (value == this.parser.Keywords.IMPORT) { throw this.parser.GenerateParseError( ErrorMessages.ALL_IMPORTS_MUST_OCCUR_AT_BEGINNING_OF_FILE, tokens.Pop()); } // TODO: check for annotations that aren't used. // https://github.com/blakeohare/crayon/issues/305 if (value == this.parser.Keywords.NAMESPACE) { return(this.ParseNamespace(tokens, owner, fileScope, annotations)); } if (value == this.parser.Keywords.CONST) { return(this.ParseConst(tokens, owner, fileScope, modifiers, annotations)); } if (value == this.parser.Keywords.FUNCTION) { return(this.ParseFunction(tokens, owner, fileScope, modifiers, annotations)); } if (value == this.parser.Keywords.CLASS) { return(this.ParseClassDefinition(tokens, owner, fileScope, modifiers, annotations)); } if (value == this.parser.Keywords.ENUM) { return(this.ParseEnumDefinition(tokens, owner, fileScope, modifiers, annotations)); } if (value == this.parser.Keywords.CONSTRUCTOR && owner is ClassDefinition) { return(this.ParseConstructor(tokens, (ClassDefinition)owner, modifiers, annotations)); } FunctionDefinition nullableFunctionDef = this.MaybeParseFunctionDefinition(tokens, owner, fileScope, annotations, modifiers); if (nullableFunctionDef != null) { return(nullableFunctionDef); } tokens.EnsureNotEof(); Token token = tokens.Peek(); throw ParserException.ThrowException( this.parser.CurrentLocale, ErrorMessages.UNEXPECTED_TOKEN_NO_SPECIFIC_EXPECTATIONS, token, token.Value); }
protected abstract FunctionDefinition ParseFunction( TokenStream tokens, TopLevelEntity nullableOwner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations);
protected virtual ClassDefinition ParseClassDefinition( TokenStream tokens, Node owner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection classAnnotations) { Token classToken = tokens.PopExpected(this.parser.Keywords.CLASS); Token classNameToken = tokens.Pop(); if (classNameToken.Type != TokenType.WORD) { throw new ParserException(classNameToken, "This is not a valid class name."); } List <Token> baseClassTokens = new List <Token>(); List <string> baseClassStrings = new List <string>(); if (tokens.PopIfPresent(":")) { if (baseClassTokens.Count > 0) { tokens.PopExpected(","); } Token baseClassToken = tokens.Pop(); string baseClassName = baseClassToken.Value; this.parser.VerifyIdentifier(baseClassToken); while (tokens.PopIfPresent(".")) { Token baseClassTokenNext = tokens.Pop(); this.parser.VerifyIdentifier(baseClassTokenNext); baseClassName += "." + baseClassTokenNext.Value; } baseClassTokens.Add(baseClassToken); baseClassStrings.Add(baseClassName); } ClassDefinition cd = new ClassDefinition( classToken, classNameToken, baseClassTokens, baseClassStrings, owner, fileScope, modifiers, classAnnotations, this.parser); tokens.PopExpected("{"); List <FunctionDefinition> methods = new List <FunctionDefinition>(); List <FieldDefinition> fields = new List <FieldDefinition>(); List <PropertyDefinition> properties = new List <PropertyDefinition>(); while (!tokens.PopIfPresent("}")) { this.ParseClassMember(tokens, fileScope, cd, methods, fields, properties); } cd.Methods = methods.ToArray(); cd.Fields = fields.ToArray(); if (cd.Constructor == null) { // This should be empty if there is no base class, or just pass along the base class' args if there is. cd.Constructor = new ConstructorDefinition( cd, ModifierCollection.EMPTY, new AnnotationCollection(parser)); if (cd.BaseClassTokens.Length > 0) { cd.Constructor.BaseToken = cd.FirstToken; cd.Constructor.SetBaseArgs(new Expression[0]); } } return(cd); }
protected abstract FieldDefinition ParseField( TokenStream tokens, ClassDefinition owner, ModifierCollection modifiers, AnnotationCollection annotations);
protected abstract ConstDefinition ParseConst( TokenStream tokens, Node owner, FileScope fileScope, ModifierCollection modifiers, AnnotationCollection annotations);