public static IReadOnlyCollection <ITypeElement> GetLinkedTypes(ITypeElement source) { var sources = new[] { source } .Concat(source.GetAllSuperTypes() .Select(x => x.GetTypeElement()) .WhereNotNull() .Where(x => !x.IsObjectClass())); var linkedTypes = sources.SelectMany(GetLinkedTypesInternal).ToList(); // TODO move to Internal method var services = source.GetPsiServices(); linkedTypes.ForEach(x => services.Finder.FindInheritors(x, new FindResultConsumer(y => { if ((y as FindResultDeclaredElement)?.DeclaredElement is ITypeElement typeElement) { linkedTypes.Add(typeElement); } return(FindExecution.Continue); }), NullProgressIndicator.Create())); return(linkedTypes); }
private static void GetSuperTypes( [NotNull] ITypeElement typeElement, BaseTypeDisplayKind baseTypeDisplayKind, ImplementedInterfacesDisplayKind implementedInterfacesDisplayKind, [CanBeNull] out DeclaredElementInstance baseType, [NotNull] out IList <DeclaredElementInstance> implementedInterfaces) { baseType = null; implementedInterfaces = EmptyList <DeclaredElementInstance> .InstanceList; var searchForBaseType = baseTypeDisplayKind != BaseTypeDisplayKind.Never && typeElement is IClass; bool searchForImplementedInterfaces = implementedInterfacesDisplayKind != ImplementedInterfacesDisplayKind.Never; if (!searchForBaseType && !searchForImplementedInterfaces) { return; } var foundInterfaces = new LocalList <DeclaredElementInstance>(); foreach (var superType in typeElement.GetAllSuperTypes()) { ITypeElement superTypeElement = superType.GetTypeElement(); if (superTypeElement is IClass || superTypeElement is IDelegate) { if (searchForBaseType) { searchForBaseType = false; if (MatchesBaseTypeDisplayKind(superTypeElement, baseTypeDisplayKind)) { baseType = new DeclaredElementInstance(superTypeElement, superType.GetSubstitution()); } if (!searchForImplementedInterfaces) { return; } } continue; } if (searchForImplementedInterfaces && superTypeElement is IInterface @interface && MatchesImplementedInterfacesDisplayKind(@interface, implementedInterfacesDisplayKind)) { foundInterfaces.Add(new DeclaredElementInstance(superTypeElement, superType.GetSubstitution())); } } implementedInterfaces = foundInterfaces.ResultingList(); }
private static void GetSuperTypes( [NotNull] ITypeElement typeElement, bool getBaseType, bool getImplementedInterfaces, [CanBeNull] out DeclaredElementInstance baseType, [NotNull] out IList <DeclaredElementInstance> implementedInterfaces) { baseType = null; implementedInterfaces = EmptyList <DeclaredElementInstance> .InstanceList; var searchForBaseType = getBaseType && typeElement is IClass; if (!searchForBaseType && !getImplementedInterfaces) { return; } var foundInterfaces = new LocalList <DeclaredElementInstance>(); foreach (var superType in typeElement.GetAllSuperTypes()) { ITypeElement superTypeElement = superType.GetTypeElement(); if (superTypeElement is IClass || superTypeElement is IDelegate) { if (searchForBaseType) { baseType = new DeclaredElementInstance(superTypeElement, superType.GetSubstitution()); searchForBaseType = false; if (!getImplementedInterfaces) { return; } } continue; } if (getImplementedInterfaces && superTypeElement is IInterface) { foundInterfaces.Add(new DeclaredElementInstance(superTypeElement, superType.GetSubstitution())); } } implementedInterfaces = foundInterfaces.ResultingList(); }
// I always have to think about what this means... // Based on Type.IsAssignableFrom(c) // "Determines whether an instance of the current Type can be assigned from an instance of the specified Type" // True if c and the current type are the same type, or if the current type is in the inheritance hierarchy of // the type c // In other words, type.IsAssignableFrom(c) is true if I can assign an instance of c to a variable of type "type" internal static bool IsAssignableFrom(this Type type, ITypeElement c) { return type.FullName == c.GetClrName().FullName || c.GetAllSuperTypes().Any(superType => type.FullName == c.GetClrName().FullName); }
// I always have to think about what this means... // Based on Type.IsAssignableFrom(c) // "Determines whether an instance of the current Type can be assigned from an instance of the specified Type" // True if c and the current type are the same type, or if the current type is in the inheritance hierarchy of // the type c // In other words, type.IsAssignableFrom(c) is true if I can assign an instance of c to a variable of type "type" internal static bool IsAssignableFrom(this Type type, ITypeElement c) { return(type.FullName == c.GetClrName().FullName || c.GetAllSuperTypes().Any(superType => type.FullName == c.GetClrName().FullName)); }