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)); } }
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); } }
/// <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); }
private static bool IsError(IEntity entity) { return(TypeSystemServices.IsError(entity)); }