@@ -897,7 +897,7 @@ If no type annotation is provided, find the value type through
897
897
t )))
898
898
(t spec)))
899
899
900
- (defun elsa--check-argument-for-index (index argument-form overloads state all-overloads overloads-errors )
900
+ (defun elsa--check-argument-for-index (index min max argument-form overloads state all-overloads overloads-errors )
901
901
(let ((good-overloads nil )
902
902
(new-overloads nil ))
903
903
(when (elsa-type-is-empty-p (elsa-get-type argument-form))
@@ -912,36 +912,62 @@ If no type annotation is provided, find the value type through
912
912
; ; error.
913
913
(setq
914
914
good-overloads
915
- (-filter
915
+ (-keep
916
916
(-lambda ((overload . overload-index))
917
- (let* ((expected (elsa-function-type-nth-arg overload index))
918
- (expected-normalized (or expected (elsa-type-mixed)))
919
- (actual (oref argument-form type))
920
- (acceptablep (elsa-type-could-assign-p expected-normalized actual)))
921
- (cond
922
- ((not expected)
923
- (push (list overload overload-index
924
- (format
925
- " Argument %s is present but the function signature does not define it. Missing overload?"
926
- (if (numberp index) (1+ index) index)))
927
- overloads-errors))
928
- ((trinary-false-p acceptablep)
929
- (push (list overload overload-index
930
- ; ; we need to sanitize the % sign in the error
931
- ; ; because it is later passed to format in
932
- ; ; `elsa-make-error' . And the "but received"
933
- ; ; string can contain arbitrary text as one
934
- ; ; possible type is (const "whatever")
935
- (elsa-with-temp-explainer explainer
936
- (elsa-explain-and-indent explainer
937
- (" Argument %s accepts type `%s' but received `%s' "
938
- (if (numberp index) (1+ index) index)
939
- (elsa-type-describe expected-normalized)
940
- (elsa-type-describe actual))
941
- (elsa-type-accept expected-normalized actual explainer))
942
- explainer))
943
- overloads-errors)))
944
- (and expected (trinary-possible-p acceptablep))))
917
+ (let* ((last-type-is-keys (elsa-type-keys-p (-last-item (oref overload args))))
918
+ (index (cond
919
+ ((< index min ) index)
920
+ ((and (symbolp max ) last-type-is-keys)
921
+ ; ; this is most likely a keyword argument,
922
+ ; ; so we check if it's a keyword and if so
923
+ ; ; pass it forward
924
+ (cond
925
+ ; ; if this index is a keyword, we just
926
+ ; ; skip to the next argument form.
927
+ ((and (elsa-form-keyword-p argument-form)
928
+ (cl-evenp (- index min )))
929
+ nil )
930
+ ; ; if the previous form was a keyword,
931
+ ; ; that's the thing we need to look up
932
+ ((elsa-form-keyword-p
933
+ (oref argument-form previous))
934
+ (elsa-form-to-lisp
935
+ (oref argument-form previous)))
936
+ (t index)))
937
+ (t index))))
938
+ (if (not index)
939
+ (list overload overload-index index)
940
+ (let* ((expected (elsa-function-type-nth-arg overload index))
941
+ (expected-normalized (or expected (elsa-type-mixed)))
942
+ (actual (oref argument-form type))
943
+ (acceptablep (elsa-type-could-assign-p expected-normalized actual)))
944
+ (cond
945
+ ((not expected)
946
+ (push (list overload overload-index
947
+ (if (numberp index) argument-form (oref argument-form previous))
948
+ (format
949
+ " Argument %s is present but the function signature does not define it. Missing overload?"
950
+ (if (numberp index) (1+ index) index)))
951
+ overloads-errors))
952
+ ((trinary-false-p acceptablep)
953
+ (push (list overload overload-index
954
+ (if (numberp index) argument-form (oref argument-form previous))
955
+ ; ; we need to sanitize the % sign in the error
956
+ ; ; because it is later passed to format in
957
+ ; ; `elsa-make-error' . And the "but received"
958
+ ; ; string can contain arbitrary text as one
959
+ ; ; possible type is (const "whatever")
960
+ (elsa-with-temp-explainer explainer
961
+ (elsa-explain-and-indent explainer
962
+ (" Argument %s accepts type `%s' but received `%s' "
963
+ (if (numberp index) (1+ index) index)
964
+ (elsa-type-describe expected-normalized)
965
+ (elsa-type-describe actual))
966
+ (elsa-type-accept expected-normalized actual explainer))
967
+ explainer))
968
+ overloads-errors)))
969
+ (when (and expected (trinary-possible-p acceptablep))
970
+ (list overload overload-index index))))))
945
971
overloads))
946
972
(if good-overloads
947
973
; ; If we have multiple overloads where the argument is of a
@@ -952,30 +978,31 @@ If no type annotation is provided, find the value type through
952
978
; ; Because the `good-overloads' are only those which accept
953
979
; ; the arguments, we can sort them by `elsa-type-accept' and
954
980
; ; pick the last (smallest) one.
955
- (if (= (length good-overloads) 1 )
956
- (setq new-overloads good-overloads)
957
- (setq new-overloads (elsa--simplify-overloads good-overloads index)))
981
+ (mapcar
982
+ (-lambda ((overload overload-index))
983
+ (cons overload overload-index))
984
+ (if (= (length good-overloads) 1 )
985
+ (setq new-overloads good-overloads)
986
+ (setq new-overloads (elsa--simplify-overloads good-overloads))))
958
987
(setq new-overloads nil )
959
988
(elsa-state-add-message state
960
989
(if (< 1 (length overloads-errors))
961
990
(let ((explainer (elsa-explainer)))
962
991
(elsa-explain-and-indent explainer
963
992
(" No overload matches this call" )
964
993
(-each (-sort (-on #'< #'cadr ) overloads-errors)
965
- (-lambda ((overload overload-index o-expl))
994
+ (-lambda ((overload overload-index _ o-expl))
966
995
(elsa-explain-and-indent explainer
967
996
(" Overload %d of %d: '%s'"
968
997
(1+ overload-index)
969
998
(length all-overloads)
970
999
(elsa-tostring overload))
971
1000
(elsa--append-explainer explainer o-expl)))))
972
- (elsa-make-error argument-form
1001
+ (elsa-make-error ( nth 2 ( car overloads-errors))
973
1002
explainer
974
1003
:code " no-overloads" ))
975
- (elsa-make-error (if (keywordp index)
976
- (oref argument-form previous)
977
- argument-form)
978
- (let ((expl-or-fmt (nth 2 (car overloads-errors))))
1004
+ (elsa-make-error (nth 2 (car overloads-errors))
1005
+ (let ((expl-or-fmt (nth 3 (car overloads-errors))))
979
1006
(if (elsa-explainer-p expl-or-fmt)
980
1007
(elsa--reset-depth expl-or-fmt)
981
1008
expl-or-fmt))
@@ -1055,38 +1082,15 @@ SCOPE and STATE are the scope and state objects."
1055
1082
(overloads (--map-indexed (cons it it-index) all-overloads)))
1056
1083
(-each-indexed args
1057
1084
(lambda (index argument-form )
1058
- (when-let ((arg-idx (cond
1059
- ((< index min ) index)
1060
- ((symbolp max )
1061
- ; ; this is most likely a
1062
- ; ; keyword argument, so we
1063
- ; ; check if it's a keyword
1064
- ; ; and if so pass it forward
1065
- (cond
1066
- ; ; if this index is a
1067
- ; ; keyword, we just skip to
1068
- ; ; the next argument form.
1069
- ((and (elsa-form-keyword-p argument-form)
1070
- (cl-evenp (- index min )))
1071
- nil )
1072
- ; ; if the previous form was
1073
- ; ; a keyword, that's the
1074
- ; ; thing we need to look up
1075
- ((elsa-form-keyword-p
1076
- (oref argument-form previous))
1077
- (elsa-form-to-lisp
1078
- (oref argument-form previous)))
1079
- (t index)))
1080
- (t index))))
1081
- (let ((check-results
1082
- (elsa--check-argument-for-index
1083
- arg-idx
1084
- argument-form overloads state
1085
- all-overloads overloads-errors)))
1086
- (setq overloads-errors
1087
- (append overloads-errors (plist-get check-results :errors )))
1088
- (setq overloads (plist-get check-results :overloads ))
1089
- (unless overloads (throw 'no-overloads nil ))))))
1085
+ (let ((check-results
1086
+ (elsa--check-argument-for-index
1087
+ index min max
1088
+ argument-form overloads state
1089
+ all-overloads overloads-errors)))
1090
+ (setq overloads-errors
1091
+ (append overloads-errors (plist-get check-results :errors )))
1092
+ (setq overloads (plist-get check-results :overloads ))
1093
+ (unless overloads (throw 'no-overloads nil )))))
1090
1094
(mapcar #'car overloads))))))
1091
1095
; ; set the return type of the form according to the return type
1092
1096
; ; of the function's declaration
0 commit comments