private static void collectImportTargetsFromType(@Nullable PyType type,
                                                   @NotNull TypeEvalContext context,
                                                   @NotNull Set<PsiNamedElement> symbols,
                                                   @NotNull Set<String> typingTypes) {
    if (type == null) {
      typingTypes.add("Any");
    }
    else if (type instanceof PyUnionType) {
      final Collection<PyType> members = ((PyUnionType)type).getMembers();
      final boolean isOptional = members.size() == 2 && members.contains(PyNoneType.INSTANCE);
      if (!PyTypingTypeProvider.isBitwiseOrUnionAvailable(context)) {
        typingTypes.add(isOptional ? "Optional" : "Union");
      }
      for (PyType pyType : members) {
        collectImportTargetsFromType(pyType, context, symbols, typingTypes);
      }
    }
    else if (type instanceof PyNamedTupleType) {
      final PyQualifiedNameOwner element = type.getDeclarationElement();
      if (element instanceof PsiNamedElement) {
        symbols.add((PsiNamedElement)element);
      }
    }
    else if (type instanceof PyCollectionType) {
      if (type instanceof PyCollectionTypeImpl) {
        final PyClass pyClass = ((PyCollectionTypeImpl)type).getPyClass();
        final String typingCollectionName = PyTypingTypeProvider.TYPING_COLLECTION_CLASSES.get(pyClass.getQualifiedName());
        if (typingCollectionName != null && type.isBuiltin()) {
          typingTypes.add(typingCollectionName);
        }
        else {
          symbols.add(pyClass);
        }
      }
      else if (type instanceof PyTupleType) {
        typingTypes.add("Tuple");
      }
      else if (type instanceof PyTypedDictType) {
        typingTypes.add("Dict");
      }
      for (PyType pyType : ((PyCollectionType)type).getElementTypes()) {
        collectImportTargetsFromType(pyType, context, symbols, typingTypes);
      }
    }
    else if (type instanceof PyClassType) {
      symbols.add(((PyClassType)type).getPyClass());
    }
    else if (type instanceof PyCallableType callableType) {
      typingTypes.add("Callable");
      for (PyCallableParameter parameter : ContainerUtil.notNullize(callableType.getParameters(context))) {
        collectImportTargetsFromType(parameter.getType(context), context, symbols, typingTypes);
      }
      collectImportTargetsFromType(callableType.getReturnType(context), context, symbols, typingTypes);
    }
    else if (type instanceof PyTypeParameterType) {
      final PyTargetExpression target = as(type.getDeclarationElement(), PyTargetExpression.class);
      if (target != null) {
        symbols.add(target);
      }
    }
    if (type instanceof PyInstantiableType && ((PyInstantiableType<?>)type).isDefinition()) {
      typingTypes.add("Type");
    }
  }
private static void collectImportTargetsFromType(@Nullable PyType type,
                                                   @NotNull TypeEvalContext context,
                                                   @NotNull Set<PsiNamedElement> symbols,
                                                   @NotNull Set<String> typingTypes)