comparison src/vim9class.c @ 33401:bb99820510ef v9.0.1959

patch 9.0.1959: Vim9: methods parameters and types are covariant Commit: https://github.com/vim/vim/commit/f3b68d4759a040ed0c4844c279ea3c779b3863ff Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri Sep 29 22:50:02 2023 +0200 patch 9.0.1959: Vim9: methods parameters and types are covariant Problem: Vim9: methods parameters and types are covariant Solution: Support contra-variant type check for object method arguments (similar to Dart). closes: #12965 closes: #13221 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
author Christian Brabandt <cb@256bit.org>
date Fri, 29 Sep 2023 23:00:04 +0200
parents 577ef266309d
children 97ceabebaeaf
comparison
equal deleted inserted replaced
33400:cbf1ccce432c 33401:bb99820510ef
2559 int 2559 int
2560 inside_class(cctx_T *cctx_arg, class_T *cl) 2560 inside_class(cctx_T *cctx_arg, class_T *cl)
2561 { 2561 {
2562 for (cctx_T *cctx = cctx_arg; cctx != NULL; cctx = cctx->ctx_outer) 2562 for (cctx_T *cctx = cctx_arg; cctx != NULL; cctx = cctx->ctx_outer)
2563 if (cctx->ctx_ufunc != NULL 2563 if (cctx->ctx_ufunc != NULL
2564 && class_instance_of(cctx->ctx_ufunc->uf_class, cl)) 2564 && class_instance_of(cctx->ctx_ufunc->uf_class, cl, TRUE))
2565 return TRUE; 2565 return TRUE;
2566 return FALSE; 2566 return FALSE;
2567 } 2567 }
2568 2568
2569 /* 2569 /*
2869 /* 2869 /*
2870 * Return TRUE when the class "cl", its base class or one of the implemented 2870 * Return TRUE when the class "cl", its base class or one of the implemented
2871 * interfaces matches the class "other_cl". 2871 * interfaces matches the class "other_cl".
2872 */ 2872 */
2873 int 2873 int
2874 class_instance_of(class_T *cl, class_T *other_cl) 2874 class_instance_of(class_T *cl, class_T *other_cl, int covariance_check)
2875 { 2875 {
2876 if (cl == other_cl) 2876 if (cl == other_cl)
2877 return TRUE; 2877 return TRUE;
2878 2878
2879 // Recursively check the base classes. 2879 if (covariance_check)
2880 for (; cl != NULL; cl = cl->class_extends) 2880 {
2881 { 2881 // Recursively check the base classes.
2882 if (cl == other_cl) 2882 for (; cl != NULL; cl = cl->class_extends)
2883 return TRUE; 2883 {
2884 // Check the implemented interfaces and the super interfaces 2884 if (cl == other_cl)
2885 for (int i = cl->class_interface_count - 1; i >= 0; --i) 2885 return TRUE;
2886 { 2886 // Check the implemented interfaces and the super interfaces
2887 class_T *intf = cl->class_interfaces_cl[i]; 2887 for (int i = cl->class_interface_count - 1; i >= 0; --i)
2888 while (intf != NULL) 2888 {
2889 { 2889 class_T *intf = cl->class_interfaces_cl[i];
2890 if (intf == other_cl) 2890 while (intf != NULL)
2891 return TRUE; 2891 {
2892 // check the super interfaces 2892 if (intf == other_cl)
2893 intf = intf->class_extends; 2893 return TRUE;
2894 } 2894 // check the super interfaces
2895 } 2895 intf = intf->class_extends;
2896 }
2897 }
2898 }
2899 }
2900 else
2901 {
2902 // contra-variance
2903 for (; other_cl != NULL; other_cl = other_cl->class_extends)
2904 if (cl == other_cl)
2905 return TRUE;
2896 } 2906 }
2897 2907
2898 return FALSE; 2908 return FALSE;
2899 } 2909 }
2900 2910
2926 emsg(_(e_class_required)); 2936 emsg(_(e_class_required));
2927 return; 2937 return;
2928 } 2938 }
2929 2939
2930 if (class_instance_of(object_tv->vval.v_object->obj_class, 2940 if (class_instance_of(object_tv->vval.v_object->obj_class,
2931 li->li_tv.vval.v_class) == TRUE) 2941 li->li_tv.vval.v_class, TRUE) == TRUE)
2932 { 2942 {
2933 rettv->vval.v_number = VVAL_TRUE; 2943 rettv->vval.v_number = VVAL_TRUE;
2934 return; 2944 return;
2935 } 2945 }
2936 } 2946 }
2937 } 2947 }
2938 else if (classinfo_tv->v_type == VAR_CLASS) 2948 else if (classinfo_tv->v_type == VAR_CLASS)
2939 { 2949 {
2940 rettv->vval.v_number = class_instance_of(object_tv->vval.v_object->obj_class, 2950 rettv->vval.v_number = class_instance_of(
2941 classinfo_tv->vval.v_class); 2951 object_tv->vval.v_object->obj_class,
2952 classinfo_tv->vval.v_class, TRUE);
2942 } 2953 }
2943 } 2954 }
2944 2955
2945 #endif // FEAT_EVAL 2956 #endif // FEAT_EVAL