private static void ClosureTo <T>(OclClassifier newElementType, IEnumerable <OclAny> source, ICollection <OclAny> dst, Func <T, OclAny> body) where T : OclAny { //Iterate over added items foreach (OclAny s in source) { //Do not add duplicates if (!dst.Contains(s)) { dst.Add(s); //Execute body for newly added item OclAny newItems = body((T)s); //Ignore null if (!IsNull(newItems)) { OclClassifier type = newItems.oclType(); if (type.ConformsToInternal(OclCollectionType.Collection(OclAny.Type))) { //Collection must be of new element type if (type.ConformsToInternal(OclCollectionType.Collection(newElementType))) { ClosureTo(newElementType, (OclCollection)newItems, dst, body); } else { throw new InvalidCastException(); } } else { //Non-collection must be kind of new element type if (type.ConformsToInternal(newElementType)) { //Add the result OclAny[] arr = { newItems }; ClosureTo(newElementType, arr, dst, body); } else { throw new InvalidCastException(); } } } } } }
internal override bool ConformsToInternal(OclClassifier cls) { //Collection conforms to OclAny if (cls == AnyType.OclAny) { return(true); } else if (cls is OclCollectionType) //Collection conforms to collection of same kind or CollectionKind of conformant element type { OclCollectionType ct = (OclCollectionType)cls; return((ct.kind == OclCollectionKind.Collection || ct.kind == kind) && elementType.ConformsToInternal(ct.elementType)); } else { return(false); } }
internal override bool ConformsToInternal(OclClassifier cls) { //Conforms to the same type and transitively to types which the parent type conforms to return(cls == this || parentClassifier.ConformsToInternal(cls)); }
internal bool conformsTo(OclTuplePart tp) { return(name == tp.name && type.ConformsToInternal(tp.type)); }