Esempio n. 1
0
        internal override void ResolveTypes(ParserContext parser, TypeResolver typeResolver)
        {
            for (int i = 0; i < this.ArgNames.Length; ++i)
            {
                this.ArgLocalIds[i].ResolvedType = typeResolver.ResolveType(this.ArgTypes[i]);
            }

            foreach (Expression defaultArg in this.DefaultValues)
            {
                if (defaultArg != null)
                {
                    defaultArg.ResolveTypes(parser, typeResolver);
                }
            }

            ClassDefinition cd = (ClassDefinition)this.Owner;

            if (this.Modifiers.HasStatic)
            {
                // already verified that there's no base constructor invocation
            }
            else if (cd.BaseClass != null)
            {
                ConstructorDefinition baseConstructor         = cd.BaseClass.Constructor;
                ResolvedType[]        baseConstructorArgTypes = baseConstructor == null
                    ? new ResolvedType[0]
                    : baseConstructor.ResolvedArgTypes;
                Expression[] baseConstructorDefaultValues = baseConstructor == null
                    ? new Expression[0]
                    : baseConstructor.DefaultValues;
                int optionalArgCount = FunctionCall.CountOptionalArgs(baseConstructorDefaultValues);
                int maxArgCount      = baseConstructorArgTypes.Length;
                int minArgCount      = maxArgCount - optionalArgCount;
                if (this.BaseArgs.Length < minArgCount || this.BaseArgs.Length > maxArgCount)
                {
                    throw new ParserException(this, "Incorrect number of arguments passed to base constructor.");
                }

                for (int i = 0; i < this.BaseArgs.Length; ++i)
                {
                    this.BaseArgs[i] = this.BaseArgs[i].ResolveTypes(parser, typeResolver);

                    ResolvedType actualType   = this.BaseArgs[i].ResolvedType;
                    ResolvedType expectedType = baseConstructorArgTypes[i];
                    if (!actualType.CanAssignToA(expectedType))
                    {
                        throw new ParserException(this.BaseArgs[i], "Argument is incorrect type.");
                    }
                    if (actualType == ResolvedType.ANY && expectedType != ResolvedType.OBJECT && expectedType != ResolvedType.ANY)
                    {
                        this.BaseArgs[i] = new Cast(this.BaseArgs[i].FirstToken, expectedType, this.BaseArgs[i], this, false);
                    }
                }
            }

            foreach (Executable line in this.Code)
            {
                line.ResolveTypes(parser, typeResolver);
            }
        }
Esempio n. 2
0
        internal override Expression Resolve(ParserContext parser)
        {
            for (int i = 0; i < this.Args.Length; ++i)
            {
                this.Args[i] = this.Args[i].Resolve(parser);
            }

            if (this.Class == null)
            {
                throw new ParserException(this.FirstToken, "No class named '" + this.Name + "'");
            }

            if (this.Class.StaticToken != null)
            {
                throw new ParserException(this.FirstToken, "Cannot instantiate a static class.");
            }

            ConstructorDefinition cons = this.Class.Constructor;

            if (cons.Annotations.IsPrivate())
            {
                bool isValidUsage =
                    this.Class == this.Owner ||     // used in a field where the owner is the class directly
                    this.Class == this.Owner.Owner; // used in a function where the owner is the method whose owner is the class.

                if (!isValidUsage)
                {
                    throw new ParserException(this.FirstToken, "The constructor for " + this.Class.NameToken.Value + " is private and cannot be invoked from outside the class.");
                }
            }

            if (this.Args.Length < cons.MinArgCount || this.Args.Length > cons.MaxArgCount)
            {
                string message = "This constructor has the wrong number of arguments. ";
                if (cons.MinArgCount == cons.MaxArgCount)
                {
                    message += "Expected " + cons.MinArgCount + " but found " + this.Args.Length;
                }
                else if (this.Args.Length < cons.MinArgCount)
                {
                    message += " At least " + cons.MinArgCount + " are required but found only " + this.Args.Length + ".";
                }
                else
                {
                    message += " At most " + cons.MaxArgCount + " are allowed but found " + this.Args.Length + ".";
                }
                throw new ParserException(this.FirstToken, message);
            }

            return(this);
        }
Esempio n. 3
0
        internal static void CheckIfThisOrBaseIsValid(Expression thisOrBase, ParserContext parser)
        {
            TopLevelEntity container        = thisOrBase.TopLevelEntity;
            string         thisOrBaseString = thisOrBase.FirstToken.Value;

            FunctionDefinition funcDef = container as FunctionDefinition;

            if (funcDef != null)
            {
                if (funcDef.Modifiers.HasStatic)
                {
                    throw new ParserException(thisOrBase, "Cannot use '" + thisOrBaseString + "' in a static method");
                }

                if (funcDef.Owner == null)
                {
                    throw new ParserException(thisOrBase, "Cannot use '" + thisOrBaseString + "' in a function that isn't a class method.");
                }
            }
            else
            {
                FieldDefinition fieldDef = container as FieldDefinition;
                if (fieldDef != null)
                {
                    if (fieldDef.Modifiers.HasStatic)
                    {
                        throw new ParserException(thisOrBase, "Cannot use '" + thisOrBaseString + "' in a static field value.");
                    }
                }
                else
                {
                    ConstructorDefinition ctorDef = container as ConstructorDefinition;
                    if (ctorDef != null && ctorDef.Modifiers.HasStatic)
                    {
                        throw new ParserException(thisOrBase, "Cannot use '" + thisOrBaseString + "' in a static constructor.");
                    }
                }
            }
        }
Esempio n. 4
0
        internal override Expression ResolveNames(ParserContext parser)
        {
            if (this.Name == "$$$")
            {
                throw new ParserException(this.FirstToken, "Core function invocations cannot stand alone and must be immediately invoked.");
            }

            if (this.Name.StartsWith("$$"))
            {
                return(new LibraryFunctionReference(this.FirstToken, this.Name.Substring(2), this.Owner));
            }

            if (this.Name == "this" || this.Name == "base")
            {
                TopLevelConstruct container = parser.CurrentCodeContainer;

                if (container is FunctionDefinition)
                {
                    FunctionDefinition funcDef = (FunctionDefinition)this.Owner;
                    if (funcDef.IsStaticMethod)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static method");
                    }

                    if (funcDef.Owner == null)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a function that isn't a class method.");
                    }
                }

                if (container is FieldDeclaration)
                {
                    if (((FieldDeclaration)container).IsStaticField)
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static field value.");
                    }
                }

                if (container is ConstructorDefinition)
                {
                    ConstructorDefinition constructor = (ConstructorDefinition)container;
                    if (constructor == ((ClassDefinition)constructor.Owner).StaticConstructor) // TODO: This check is silly. Add an IsStatic field to ConstructorDefinition.
                    {
                        throw new ParserException(this.FirstToken, "Cannot use '" + this.Name + "' in a static constructor.");
                    }
                }

                if (this.Name == "this")
                {
                    return(new ThisKeyword(this.FirstToken, this.Owner));
                }
                return(new BaseKeyword(this.FirstToken, this.Owner));
            }

            NamespaceReferenceTemplate nrt = this.Owner.FileScope.FileScopeEntityLookup.DoNamespaceLookup(this.Name, this.Owner);

            if (nrt != null)
            {
                return(new NamespaceReference(this.FirstToken, this.Owner, nrt));
            }

            TopLevelConstruct exec = this.Owner.FileScope.FileScopeEntityLookup.DoEntityLookup(this.Name, this.Owner);

            if (exec != null)
            {
                return(Resolver.ResolverPipeline.ConvertStaticReferenceToExpression(exec, this.FirstToken, this.Owner));
            }

            return(this);
        }