Repository: opencv/opencv
File: modules/js/generator/embindgen.py (Python)

Code before:
        wrappers = []

        for index, variant in enumerate(func.variants):

            factory = False
            if class_info and 'Ptr<' in variant.rettype:

                factory = True
                base_class_name = variant.rettype
                base_class_name = base_class_name.replace("Ptr<","").replace(">","").strip()
                if base_class_name in self.classes:
                    self.classes[base_class_name].has_smart_ptr = True
                else:
                    print(base_class_name, ' not found in classes for registering smart pointer using ', class_info.name, 'instead')
                    self.classes[class_info.name].has_smart_ptr = True

            def_args = []
            has_def_param = False

            # Return type
            ret_type = 'void' if variant.rettype.strip() == '' else variant.rettype
            # FIX: Ensure namespaced smart-pointer return types in factory methods, e.g.:
            #      Ptr<EdgeDrawing> → Ptr<cv::ximgproc::EdgeDrawing>
            if factory and class_info is not None and ret_type.startswith('Ptr<'):
                inner = ret_type[len('Ptr<'):-1].strip()
                if '::' not in inner:
                    ret_type = 'Ptr<%s>' % class_info.cname

            if ret_type.startswith('Ptr'):  # smart pointer
                ptr_type = ret_type.replace('Ptr<', '').replace('>', '')
                if ptr_type in type_dict:
                    ret_type = type_dict[ptr_type]
                for key in type_dict:
                    if key in ret_type:
                        ret_type = re.sub(r"\b" + key + r"\b", type_dict[key], ret_type) 
            arg_types = []
            unwrapped_arg_types = []
            for arg in variant.args:
                arg_type = None
                if arg.tp in type_dict:
                    arg_type = type_dict[arg.tp]
                else:
                    arg_type = arg.tp
                # Add default value
                if with_default_params and arg.defval != '':
                    def_args.append(arg.defval);
                arg_types.append(arg_type)
                unwrapped_arg_types.append(arg_type)

            # Function attribute
            func_attribs = ''

Review comment (suggestion):
The fix assumes that the unqualified type inside `Ptr<...>` always refers to the class represented by `class_info`. However, this may not be correct if a method returns a pointer to a different class. Consider checking if `inner` matches `class_info.name` before replacing it with `class_info.cname`. For example:

```python
if factory and class_info is not None and ret_type.startswith('Ptr<'):
    inner = ret_type[len('Ptr<'):-1].strip()
    if '::' not in inner and inner == class_info.name:
        ret_type = 'Ptr<%s>' % class_info.cname
```

This ensures we only qualify the type when it actually refers to the current class.
```suggestion
                if '::' not in inner and inner == class_info.name:
```

Code after:
        wrappers = []

        for index, variant in enumerate(func.variants):

            factory = False
            if class_info and 'Ptr<' in variant.rettype:

                factory = True
                base_class_name = variant.rettype
                base_class_name = base_class_name.replace("Ptr<","").replace(">","").strip()
                if base_class_name in self.classes:
                    self.classes[base_class_name].has_smart_ptr = True
                else:
                    print(base_class_name, ' not found in classes for registering smart pointer using ', class_info.name, 'instead')
                    self.classes[class_info.name].has_smart_ptr = True

            def_args = []
            has_def_param = False

            # Return type
            ret_type = 'void' if variant.rettype.strip() == '' else variant.rettype
            # FIX: Ensure namespaced smart-pointer return types in factory methods, e.g.:
            #      Ptr<EdgeDrawing> → Ptr<cv::ximgproc::EdgeDrawing>
            if factory and class_info is not None and ret_type.startswith('Ptr<'):
                inner = ret_type[len('Ptr<'):-1].strip()
                if '::' not in inner and inner == class_info.name:
                    ret_type = 'Ptr<%s>' % class_info.cname

            if ret_type.startswith('Ptr'):  # smart pointer
                ptr_type = ret_type.replace('Ptr<', '').replace('>', '')
                if ptr_type in type_dict:
                    ret_type = type_dict[ptr_type]
                for key in type_dict:
                    if key in ret_type:
                        ret_type = re.sub(r"\b" + key + r"\b", type_dict[key], ret_type)
            arg_types = []
            unwrapped_arg_types = []
            for arg in variant.args:
                arg_type = None
                if arg.tp in type_dict:
                    arg_type = type_dict[arg.tp]
                else:
                    arg_type = arg.tp
                # Add default value
                if with_default_params and arg.defval != '':
                    def_args.append(arg.defval);
                arg_types.append(arg_type)
                unwrapped_arg_types.append(arg_type)

            # Function attribute
            func_attribs = ''