private static bool FormalGenericTypeConformToBase(IFormalGenericType derivedType, ICompiledType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Result &= derivedType.FormalGeneric.ResolvedConformanceTable.IsSealed; if (derivedType.FormalGeneric.ResolvedConformanceTable.Count > 0) { Result &= FormalGenericTypeConformToBaseWithConformance(derivedType, baseType, errorList, sourceLocation); } else if (baseType != ClassType.ClassAnyType && baseType != ClassType.ClassAnyReferenceType && baseType != ClassType.ClassAnyValueType) { errorList.AddError(new ErrorInsufficientConstraintConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.IsReference && !derivedType.IsReference) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } if (baseType.IsValue && !derivedType.IsValue) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }
private static bool IsDirectFormalGenericDescendantOf(IFormalGenericType derivedType, IClassType baseType) { bool Result = false; Result |= ConformToBaseAny(derivedType, baseType); foreach (IConstraint Item in derivedType.FormalGeneric.ConstraintList) { if (Item.ResolvedParentType.Item is IClassType Parent) { Result |= TypeConformDirectlyToBase(Parent, baseType, ErrorList.Ignored, ErrorList.NoLocation); } } return(Result); }
private static bool FormalGenericTypeConformToBaseWithConformance(IFormalGenericType derivedType, ICompiledType baseType, IErrorList errorList, ISource sourceLocation) { bool ConformantConstraintFound = false; foreach (KeyValuePair <ITypeName, ICompiledType> ConformingEntry in derivedType.FormalGeneric.ResolvedConformanceTable) { ICompiledType ConformingType = ConformingEntry.Value; ConformantConstraintFound |= TypeConformToBase(ConformingType, baseType, ErrorList.Ignored, ErrorList.NoLocation, isConversionAllowed: false); } if (!ConformantConstraintFound) { errorList.AddError(new ErrorInsufficientConstraintConformance(sourceLocation, derivedType, baseType)); } return(ConformantConstraintFound); }
/// <summary> /// Applies the rule. /// </summary> /// <param name="node">The node instance to modify.</param> /// <param name="data">Private data from CheckConsistency().</param> public override void Apply(IGeneric node, object data) { node.ResolvedConformanceTable.Seal(); Debug.Assert(node.ResolvedGenericType.IsAssigned); IFormalGenericType GenericType = node.ResolvedGenericType.Item; BaseNode.CopySemantic CopyConstraint = (BaseNode.CopySemantic)data; switch (CopyConstraint) { case BaseNode.CopySemantic.Any: Debug.Assert(!GenericType.IsReference); Debug.Assert(!GenericType.IsValue); break; case BaseNode.CopySemantic.Reference: Debug.Assert(GenericType.IsReference); Debug.Assert(!GenericType.IsValue); break; case BaseNode.CopySemantic.Value: Debug.Assert(!GenericType.IsReference); Debug.Assert(GenericType.IsValue); break; } GenericType.ConformanceTable.Seal(); foreach (IConstraint Constraint in node.ConstraintList) { if (Constraint.ResolvedTypeWithRename.IsAssigned && Constraint.ResolvedTypeWithRename.Item is IClassType AsClassType) { foreach (KeyValuePair <IFeatureName, IFeatureInstance> Entry in AsClassType.FeatureTable) { Debug.Assert(!GenericType.FeatureTable.ContainsKey(Entry.Key)); GenericType.FeatureTable.Add(Entry); } } } GenericType.FeatureTable.Seal(); }
/// <summary> /// Initializes a new instance of the <see cref="CSharpFormalGenericType"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly type from which the C# type is created.</param> protected CSharpFormalGenericType(ICSharpContext context, IFormalGenericType source) : base(context, source) { Generic = context.GetGeneric(Source.FormalGeneric); NumberType = CSharpNumberTypes.NotApplicable; foreach (ICSharpConstraint Constraint in Generic.ConstraintList) { if (Constraint.TypeWithRename is ICSharpClassType AsClassType) { if (AsClassType.IsNumberType) { if (NumberType == CSharpNumberTypes.NotApplicable) { NumberType = CSharpNumberTypes.Unknown; } switch (AsClassType.NumberType) { case CSharpNumberTypes.Unknown: if (NumberType == CSharpNumberTypes.NotApplicable) { NumberType = CSharpNumberTypes.Unknown; } break; case CSharpNumberTypes.Integer: Debug.Assert(NumberType != CSharpNumberTypes.Real); NumberType = CSharpNumberTypes.Integer; break; case CSharpNumberTypes.Real: Debug.Assert(NumberType != CSharpNumberTypes.Integer); NumberType = CSharpNumberTypes.Real; break; } } } } }
/// <summary> /// Applies the rule. /// </summary> /// <param name="node">The node instance to modify.</param> /// <param name="data">Private data from CheckConsistency().</param> public override void Apply(ISimpleType node, object data) { ITypeName ValidTypeName = ((Tuple <ITypeName, ICompiledType>)data).Item1; ICompiledType ValidType = ((Tuple <ITypeName, ICompiledType>)data).Item2; node.TypeNameSource.Item = ValidTypeName; node.TypeSource.Item = ValidType; node.ValidTypeSource.Item = "Set"; IIdentifier ClassIdentifier = (IIdentifier)node.ClassIdentifier; string ValidIdentifier = ClassIdentifier.ValidText.Item; IClass EmbeddingClass = node.EmbeddingClass; ISealableDictionary <string, ICompiledType> LocalGenericTable = EmbeddingClass.LocalGenericTable; if (LocalGenericTable.ContainsKey(ValidIdentifier)) { IFormalGenericType FormalGeneric = (IFormalGenericType)LocalGenericTable[ValidIdentifier]; node.FormalGenericSource.Item = FormalGeneric; node.FormalGenericNameSource.Item = FormalGeneric.ResolvedTypeName; } }
/// <summary> /// Compares two types. /// </summary> /// <param name="type1">The first type.</param> /// <param name="type2">The second type.</param> public static bool TypesHaveIdenticalSignature(IFormalGenericType type1, IFormalGenericType type2) { return(type1.FormalGeneric == type2.FormalGeneric); }
private bool IsTypeReady(ISimpleType node, out object data) { data = null; bool IsReady = true; ITypeName ValidTypeName = null; ICompiledType ValidType = null; IError Error = null; IClass EmbeddingClass = node.EmbeddingClass; IFeature EmbeddingFeature = node.EmbeddingFeature; IIdentifier ClassIdentifier = (IIdentifier)node.ClassIdentifier; Debug.Assert(ClassIdentifier.ValidText.IsAssigned); string ValidIdentifier = ClassIdentifier.ValidText.Item; ISealableDictionary <string, IImportedClass> ImportedClassTable = EmbeddingClass.ImportedClassTable; ISealableDictionary <string, ICompiledType> LocalGenericTable = EmbeddingClass.LocalGenericTable; ISealableDictionary <IFeatureName, ISealableDictionary <string, IClass> > LocalExportTable = EmbeddingClass.LocalExportTable; ISealableDictionary <IFeatureName, ITypedefType> LocalTypedefTable = EmbeddingClass.LocalTypedefTable; ISealableDictionary <IFeatureName, IDiscrete> LocalDiscreteTable = EmbeddingClass.LocalDiscreteTable; ISealableDictionary <IFeatureName, IFeatureInstance> LocalFeatureTable = EmbeddingClass.LocalFeatureTable; IsReady &= ImportedClassTable.IsSealed; IsReady &= LocalGenericTable.IsSealed; IsReady &= LocalExportTable.IsSealed; IsReady &= LocalTypedefTable.IsSealed; IsReady &= LocalDiscreteTable.IsSealed; IsReady &= LocalFeatureTable.IsSealed; IsReady &= EmbeddingClass.ResolvedClassType.IsAssigned; if (IsReady) { if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.Any.Name.ToUpperInvariant()) { GetBaseClassType(Class.ClassAny, out ValidTypeName, out ValidType); } else if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.AnyReference.Name.ToUpperInvariant()) { GetBaseClassType(Class.ClassAnyReference, out ValidTypeName, out ValidType); } else if (ValidIdentifier.ToUpperInvariant() == LanguageClasses.AnyValue.Name.ToUpperInvariant()) { GetBaseClassType(Class.ClassAnyValue, out ValidTypeName, out ValidType); } else if (ImportedClassTable.ContainsKey(ValidIdentifier)) { IImportedClass Imported = ImportedClassTable[ValidIdentifier]; IClass BaseClass = Imported.Item; IsReady = CheckValidityAsClass(BaseClass, out ValidTypeName, out ValidType, out bool IsInvalidGeneric); if (IsInvalidGeneric) { Error = new ErrorGenericClass(ClassIdentifier, ValidIdentifier); } } else if (LocalGenericTable.ContainsKey(ValidIdentifier)) { IFormalGenericType FormalGeneric = (IFormalGenericType)LocalGenericTable[ValidIdentifier]; GetGenericType(FormalGeneric, out ValidTypeName, out ValidType); } else if (FeatureName.TableContain(LocalTypedefTable, ValidIdentifier, out IFeatureName Key, out ITypedefType DefinedType)) { IsReady = CheckValidityAsTypedef(DefinedType, out ValidTypeName, out ValidType); } else { Error = new ErrorUnknownIdentifier(ClassIdentifier, ValidIdentifier); } }
/// <summary> /// Create a new C# type. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly type from which the C# type is created.</param> public static ICSharpFormalGenericType Create(ICSharpContext context, IFormalGenericType source) { return(new CSharpFormalGenericType(context, source)); }
private static bool TypeConformToFormalGenericType(ICompiledType derivedType, IFormalGenericType baseType, IErrorList errorList, ISource sourceLocation) { bool Result = true; Result &= baseType.FormalGeneric.ResolvedConformanceTable.IsSealed; foreach (KeyValuePair <ITypeName, ICompiledType> ConformingEntry in baseType.FormalGeneric.ResolvedConformanceTable) { ICompiledType ConformingType = ConformingEntry.Value; Result &= TypeConformToBase(derivedType, ConformingType, errorList, sourceLocation, isConversionAllowed: false); } if (!derivedType.IsReference && baseType.IsReference) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } if (!derivedType.IsValue && baseType.IsValue) { errorList.AddError(new ErrorReferenceValueConformance(sourceLocation, derivedType, baseType)); Result = false; } return(Result); }