Mercurial > vim
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 |