예제 #1
0
        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);
        }
예제 #2
0
 protected abstract FunctionDefinition ParseFunction(
     TokenStream tokens,
     TopLevelEntity nullableOwner,
     FileScope fileScope,
     ModifierCollection modifiers,
     AnnotationCollection annotations);
예제 #3
0
        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);
        }
예제 #4
0
 protected abstract FieldDefinition ParseField(
     TokenStream tokens,
     ClassDefinition owner,
     ModifierCollection modifiers,
     AnnotationCollection annotations);
예제 #5
0
 protected abstract ConstDefinition ParseConst(
     TokenStream tokens,
     Node owner,
     FileScope fileScope,
     ModifierCollection modifiers,
     AnnotationCollection annotations);