public TypeRelation CompareTo(XCapability o, XTypeRecursionTracker memory) { int equal = 0; int ext = 0; int sup = 0; switch (this.Name.CompareTo(o.Name)) { case TypeRelation.EQUAL: equal++; break; case TypeRelation.EXTENDS: ext++; break; case TypeRelation.SUPER: sup++; break; case TypeRelation.NONE: return(TypeRelation.NONE); default: break; } if (this.ComplexType != null && o.ComplexType != null) { switch (this.ComplexType.CompareTo(o.ComplexType, memory)) { case TypeRelation.EQUAL: equal++; break; case TypeRelation.EXTENDS: ext++; break; case TypeRelation.SUPER: sup++; break; case TypeRelation.NONE: return(TypeRelation.NONE); default: break; } } else if ((this.ComplexType == null) != (this.ComplexType == null)) { return(TypeRelation.NONE); } if (this.ValueType != XValueType.COMPLEX && this.ValueType == o.ValueType) { equal++; } switch (Utils.CompareCardinality(this.Cardinality, o.Cardinality)) { case TypeRelation.EQUAL: equal++; break; case TypeRelation.EXTENDS: ext++; break; case TypeRelation.SUPER: sup++; break; case TypeRelation.NONE: return(TypeRelation.NONE); default: break; } int all = equal + ext + sup; if (all == equal) { return(TypeRelation.EQUAL); } if (all == equal + ext) { return(TypeRelation.EXTENDS); } if (all == equal + sup) { return(TypeRelation.SUPER); } // mixed content, inconclusive return(TypeRelation.NONE); }
/// <summary> /// Perform type comparison by using the given memory to avoid infinite recursion. /// </summary> /// <param name="o">type to check against</param> /// <param name="memory">memory to keep track the traversed types</param> /// <returns>relation</returns> public TypeRelation CompareTo(XType o, XTypeRecursionTracker memory) { memory.EnterFirst(this); memory.EnterSecond(o); int equal = 0; int ext = 0; int sup = 0; primary: foreach (XCapability c0 in this.Capabilities) { if (c0.ComplexType != null) { int fidx = memory.IndexFirst(c0.ComplexType); // is this a recursive call? if (fidx >= 0) { foreach (XCapability c1 in o.Capabilities) { if (c1.ComplexType != null) { int sidx = memory.IndexSecond(c1.ComplexType); if (sidx == fidx) { equal++; goto primary; } } } // we don't have any recursive type on the other side goto primary; } } inner: foreach (XCapability c1 in o.Capabilities) { if (c0.Name.CompareTo(c1.Name) != TypeRelation.NONE) { switch (c0.CompareTo(c1, memory)) { case TypeRelation.EQUAL: equal++; goto inner; case TypeRelation.EXTENDS: ext++; goto inner; case TypeRelation.SUPER: sup++; goto inner; default: break; } } } } memory.LeaveFirst(); memory.LeaveSecond(); // common int all = equal + ext + sup; if (all < Capabilities.Count && all < o.Capabilities.Count) { return(TypeRelation.NONE); } int diff = Capabilities.Count - o.Capabilities.Count; if (all == equal) { return(Utils.CompareToTypeRelation(diff)); } else if (all == equal + ext && diff >= 0) { return(TypeRelation.EXTENDS); } else if (all == equal + sup && diff <= 0) { return(TypeRelation.SUPER); } // mixed content, inconclusive return(TypeRelation.NONE); }