private void CreateSubtypeRelation(AstNode node, IType right, IType left, SubtypeKind kind, bool isRightTypeThis) { var leftType = GetTypeOrCreateExternal(left); var rightType = GetTypeOrCreateExternal(right); var currentMethod = node.GetParent <MethodDeclaration>() ?? node.GetParent <ConstructorDeclaration>() as EntityDeclaration ?? node.GetParent <PropertyDeclaration>(); string fromReference = currentMethod == null ? "(field initializer)" : currentMethod.Name; var currentDeclaringTypeResolve = Resolver.Resolve(node.GetParent <TypeDeclaration>()); fromReference += " in " + currentDeclaringTypeResolve.Type.FullName; //left is the parent, right is the child for (int i = 0; i < left.TypeArguments.Count && i < right.TypeArguments.Count; i++) { var leftArg = left.TypeArguments[i]; var rightArg = right.TypeArguments[i]; var leftArgument = GetTypeOrCreateExternal(leftArg); var rightArgument = GetTypeOrCreateExternal(rightArg); CreateSubtypeRelation(node, leftArg, rightArg, SubtypeKind.CovariantTypeArgument, false); CreateSubtypeRelation(node, rightArg, leftArg, SubtypeKind.ContravariantTypeArgument, false); } if (rightType.IsChildOf(leftType)) { rightType.HasSubtypeToObject |= leftType.IsObject; var relations = rightType.GetPathTo(leftType); foreach (var item in relations) { item.Subtypes.Add(new Subtype(item.BaseType == leftType && item.DerivedType == rightType, kind, fromReference)); } } if (isRightTypeThis && kind == SubtypeKind.Parameter) { foreach (var derivedType in rightType.AllDerivedTypes()) { var relation = derivedType.GetImmediateParent(rightType); relation.Subtypes.Add(new Subtype(derivedType.IsDirectChildOf(rightType), SubtypeKind.ThisChangingType, fromReference)); } } }
public Subtype(bool isDirect, SubtypeKind kind, string fromReference) { _isDirect = isDirect; _kind = kind; _fromReference = fromReference; }