internal override void Resolve(ParserContext parser)
        {
            if (parser.IsInClass)
            {
                throw new ParserException(this.FirstToken, "Nested classes aren't a thing, yet.");
            }

            if (parser.IsReservedKeyword(this.NameToken.Value))
            {
                throw new ParserException(this.NameToken, "'" + this.NameToken.Value + "' is a reserved keyword.");
            }

            parser.CurrentClass = this;

            for (int i = 0; i < this.Fields.Length; ++i)
            {
                FieldDeclaration field = this.Fields[i];
                field.Resolve(parser);
                this.Fields[i] = field;
                if (this.StaticToken != null && !field.IsStaticField)
                {
                    throw new ParserException(field.FirstToken, "Cannot have a non-static field in a static class.");
                }
            }

            for (int i = 0; i < this.Methods.Length; ++i)
            {
                FunctionDefinition funcDef = this.Methods[i];
                funcDef.Resolve(parser);
                this.Methods[i] = funcDef;
                if (this.StaticToken != null && !funcDef.IsStaticMethod)
                {
                    throw new ParserException(funcDef.FirstToken, "Cannot have a non-static method in a static class.");
                }
            }

            this.Constructor.Resolve(parser);
            if (this.StaticToken != null && !this.Constructor.IsDefault)
            {
                throw new ParserException(this.Constructor.FirstToken, "Static classes cannot have a non-static constructor.");
            }

            if (this.StaticConstructor != null)
            {
                this.StaticConstructor.Resolve(parser);
            }

            parser.CurrentClass = null;

            bool hasABaseClass        = this.BaseClass != null;
            bool callsBaseConstructor = this.Constructor.BaseToken != null;

            if (hasABaseClass)
            {
                if (this.BaseClass.FinalToken != null)
                {
                    throw new ParserException(this.FirstToken, "This class extends from " + this.BaseClass.NameToken.Value + " which is marked as final.");
                }

                if (this.BaseClass.StaticToken != null)
                {
                    throw new ParserException(this.FirstToken, "This class extends from " + this.BaseClass.NameToken.Value + " which is marked as static.");
                }
            }

            if (hasABaseClass && callsBaseConstructor)
            {
                Expression[] defaultValues = this.BaseClass.Constructor.DefaultValues;
                int          maxValues     = defaultValues.Length;
                int          minValues     = 0;
                for (int i = 0; i < maxValues; ++i)
                {
                    if (defaultValues[i] == null)
                    {
                        minValues++;
                    }
                    else
                    {
                        break;
                    }
                }
                int baseArgs = this.Constructor.BaseArgs.Length;
                if (baseArgs < minValues || baseArgs > maxValues)
                {
                    throw new ParserException(this.Constructor.BaseToken, "Invalid number of arguments passed to base constructor.");
                }
            }
            else if (hasABaseClass && !callsBaseConstructor)
            {
                if (this.BaseClass.Constructor != null)
                {
                    throw new ParserException(this.FirstToken, "The base class of this class has a constructor which must be called.");
                }
            }
            else if (!hasABaseClass && callsBaseConstructor)
            {
                throw new ParserException(this.Constructor.BaseToken, "Cannot call base constructor without a base class.");
            }
            else // (!hasABaseClass && !callsBaseConstructor)
            {
                // yeah, that's fine.
            }
        }
Beispiel #2
0
        internal override void Resolve(ParserContext parser)
        {
            for (int i = 0; i < this.Fields.Length; ++i)
            {
                FieldDefinition field = this.Fields[i];
                field.Resolve(parser);
                this.Fields[i] = field;
            }

            for (int i = 0; i < this.Methods.Length; ++i)
            {
                FunctionDefinition funcDef = this.Methods[i];
                funcDef.Resolve(parser);
                this.Methods[i] = funcDef;
            }

            this.Constructor.Resolve(parser);

            if (this.StaticConstructor != null)
            {
                this.StaticConstructor.Resolve(parser);
            }

            bool hasABaseClass        = this.BaseClass != null;
            bool callsBaseConstructor = this.Constructor.BaseToken != null;

            if (hasABaseClass && callsBaseConstructor)
            {
                Expression[] defaultValues = this.BaseClass.Constructor.DefaultValues;
                int          maxValues     = defaultValues.Length;
                int          minValues     = 0;
                for (int i = 0; i < maxValues; ++i)
                {
                    if (defaultValues[i] == null)
                    {
                        minValues++;
                    }
                    else
                    {
                        break;
                    }
                }
                int baseArgs = this.Constructor.BaseArgs.Length;
                if (baseArgs < minValues || baseArgs > maxValues)
                {
                    throw new ParserException(this.Constructor.BaseToken, "Invalid number of arguments passed to base constructor.");
                }
            }
            else if (hasABaseClass && !callsBaseConstructor)
            {
                if (this.BaseClass.Constructor != null)
                {
                    if (this.BaseClass.Constructor.MinArgCount > 0)
                    {
                        throw new ParserException(this, "The base class of this class has a constructor which must be called.");
                    }
                }
            }
            else if (!hasABaseClass && callsBaseConstructor)
            {
                throw new ParserException(this.Constructor.BaseToken, "Cannot call base constructor without a base class.");
            }
            else // (!hasABaseClass && !callsBaseConstructor)
            {
                // yeah, that's fine.
            }
        }