Repository: godot
Issue: C++ can not expose properly typed properties that return Script classes
Labels: bug,topic:gdscript,needs testing,topic:gdextension

### Tested versions

4.3-stable

### System information

Windows 11

### Issue description

I am currently trying to add some properties to a C++ class that return GDScript classes. While everything is linked correctly in the documentation and autocomplete is working, 
![image](https://github.com/user-attachments/assets/39f90613-3900-4e90-b309-895dbf52668e)

trying to access the properties or casting them to the GDScript type results in
![image](https://github.com/user-attachments/assets/e6182fec-6566-4ab3-a655-33fcf1fdc1f9)

Maybe I am doing something wrong but it seems the issue is this part here:

https://github.com/godotengine/godot/blob/ce8a837aab2568f9cdc41b4b410c478b0cd711fc/modules/gdscript/gdscript_analyzer.cpp#L5710

Where `p_source` is `SCRIPT` and `p_target` is `CLASS`
When I implement the same functionality in GDScript, both `p_source` and `p_target` are `CLASS`


### Steps to reproduce

-

### Minimal reproduction project (MRP)

```
class ManagerMethodBind : public MethodBind
{
protected:
    Variant::Type _gen_argument_type(int p_arg) const override 
    {
        return Variant::OBJECT;
    }

    PropertyInfo _gen_argument_type_info(int p_arg) const override 
    {
        return PropertyInfo(m_class);
    }

public:
#ifdef DEBUG_METHODS_ENABLED
    GodotTypeInfo::Metadata get_argument_meta(int p_arg) const override 
    {
        return GodotTypeInfo::METADATA_NONE;
    }
#endif

    Variant call(Object* p_object, const Variant** p_args, int p_arg_count, Callable::CallError& r_error) const override 
    {
        return static_cast<Manager*>(p_object)->get_manager(m_name);
    }

    void validated_call(Object* p_object, const Variant** p_args, Variant* r_ret) const override 
    {
        *r_ret = static_cast<Manager*>(p_object)->get_manager(m_name);
    }

    void ptrcall(Object* p_object, const void** p_args, void* r_ret) const override 
    {
        *static_cast<Object**>(r_ret) = static_cast<Manager*>(p_object)->get_manager(m_name);
    }

    ManagerMethodBind(StringName name, StringName cls)
        : m_class(cls)
    {
        m_name =Manager::get_manager_name(cls);
        set_name(name);
        _set_returns(true);
        _generate_argument_types(0);
        set_argument_count(0);
    }

private:
    String m_name;
    StringName m_class;
};

void get_script_managers(const String& p_class, List<StringName>& r_inheriters)
{
    Array script_classes = ProjectSettings::get_singleton()->get_global_class_list();
    for (int i = 0; i < script_classes.size(); i++) 
    {
        Dictionary c = script_classes[i];
        if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) 
        {
            continue;
        }
        if (String(c["base"]) == p_class)
        {
            r_inheriters.push_back(c["class"]);
        }
    }
}

void Manager::_bind_methods()
{
    auto bind_manager = [](const StringName& mgr)
    {
        const auto method_name = "get_" + get_manager_name(mgr);
        ClassDB::bind_method_custom(get_class_static(), memnew(ManagerMethodBind(method_name, mgr)));
        ADD_PROPERTY(PropertyInfo(Variant::OBJECT, get_manager_name(mgr), 
            PROPERTY_HINT_RESOURCE_TYPE, mgr, PROPERTY_USAGE_READ_ONLY), "", method_name.utf8());
    };

    List<StringName> game;
    ClassDB::get_inheriters_from_class("GameManager", &game);
    get_script_managers("GameManager", game);
    ADD_GROUP("Game", "");
    for (const auto& mgr : game)
    {
        bind_manager(mgr);
    }
}