Exemple #1
0
        void CheckBaseTypes(ClassDefinition node)
        {
            IType baseClass = null;

            foreach (TypeReference baseTypeRef in node.BaseTypes)
            {
                IType baseType = GetType(baseTypeRef);
                if (baseType.IsInterface)
                {
                    continue;
                }

                if (null != baseClass)
                {
                    Error(CompilerErrorFactory.ClassAlreadyHasBaseType(baseTypeRef, node.Name, baseClass));
                    continue;
                }

                baseClass = baseType;
                if (baseClass.IsFinal && !TypeSystemServices.IsError(baseClass))
                {
                    Error(CompilerErrorFactory.CannotExtendFinalType(baseTypeRef, baseClass));
                }
            }

            if (null == baseClass)
            {
                node.BaseTypes.Insert(0, CodeBuilder.CreateTypeReference(TypeSystemServices.ObjectType));
            }
        }
Exemple #2
0
        public void ResolveArrayTypeReference(ArrayTypeReference node)
        {
            if (null != node.Entity)
            {
                return;
            }

            ResolveTypeReference(node.ElementType);

            IType elementType = TypeSystemServices.GetType(node.ElementType);

            if (TypeSystemServices.IsError(elementType))
            {
                node.Entity = TypeSystemServices.ErrorEntity;
            }
            else
            {
                int rank = null == node.Rank ? 1 : (int)node.Rank.Value;
                node.Entity = elementType.MakeArrayType(rank);
            }
        }
Exemple #3
0
        /// <summary>
        /// Constructs an entity from a generic definition and arguments, after ensuring the construction is valid.
        /// </summary>
        /// <param name="definition">The generic definition entity.</param>
        /// <param name="constructionNode">The node in which construction occurs.</param>
        /// <param name="typeArguments">The generic type arguments to substitute for generic parameters.</param>
        /// <returns>The constructed entity.</returns>
        public IEntity ConstructEntity(Node constructionNode, IEntity definition, IType[] typeArguments)
        {
            // Ensure definition is a valid entity
            if (definition == null || TypeSystemServices.IsError(definition))
            {
                return(TypeSystemServices.ErrorEntity);
            }

            // Ambiguous generic constructions are handled separately
            if (definition.EntityType == EntityType.Ambiguous)
            {
                return(ConstructAmbiguousEntity(constructionNode, (Ambiguous)definition, typeArguments));
            }

            // Check that the construction is valid
            if (!CheckGenericConstruction(constructionNode, definition, typeArguments, true))
            {
                return(TypeSystemServices.ErrorEntity);
            }

            return(MakeGenericEntity(definition, typeArguments));
        }
        private bool MaintainsParameterConstraints(IGenericParameter parameter, IType argument)
        {
            if (argument == null || TypeSystemServices.IsError(argument))
            {
                return(true);
            }

            if (argument == parameter)
            {
                return(true);
            }

            if (argument == _typeSystemServices.VoidType)
            {
                Errors.Add(CompilerErrorFactory.InvalidGenericParameterType(ConstructionNode, argument));
                return(false);
            }

            bool valid = true;

            // Check type semantics constraints
            if (parameter.IsClass && !(argument.IsClass || argument.IsInterface))
            {
                Errors.Add(CompilerErrorFactory.GenericArgumentMustBeReferenceType(ConstructionNode, parameter, argument));
                valid = false;
            }

            if (parameter.IsValueType && !argument.IsValueType)
            {
                Errors.Add(CompilerErrorFactory.GenericArgumentMustBeValueType(ConstructionNode, parameter, argument));
                valid = false;
            }
            // Don't check for default constructor constraint if value type constraint failed
            else if (parameter.MustHaveDefaultConstructor && !HasDefaultConstructor(argument))
            {
                Errors.Add(CompilerErrorFactory.GenericArgumentMustHaveDefaultConstructor(ConstructionNode, parameter, argument));
                valid = false;
            }

            // Check base type constraints
            IType[] baseTypes = parameter.GetTypeConstraints();
            if (baseTypes != null)
            {
                foreach (IType baseType in baseTypes)
                {
                    // Foo<T> where T : Foo<T>
                    if (null != _definition &&
                        TypeCompatibilityRules.IsAssignableFrom(baseType, _definition) &&
                        argument == _constructionNode.ParentNode.Entity)
                    {
                        continue;
                    }

                    // Don't check for System.ValueType supertype constraint
                    // if parameter also has explicit value type constraint
                    if (baseType == _typeSystemServices.ValueTypeType && parameter.IsValueType)
                    {
                        continue;
                    }

                    if (!TypeCompatibilityRules.IsAssignableFrom(baseType, argument))
                    {
                        Errors.Add(CompilerErrorFactory.GenericArgumentMustHaveBaseType(ConstructionNode, parameter, argument, baseType));
                        valid = false;
                    }
                }
            }

            return(valid);
        }
Exemple #5
0
 private static bool IsError(IEntity entity)
 {
     return(TypeSystemServices.IsError(entity));
 }