mirror of
https://github.com/janet-lang/janet
synced 2026-05-22 05:12:14 +00:00
More tweaks for named arity linting.
Handle more edge cases where &named is combined with &opt
This commit is contained in:
+9
-4
@@ -599,17 +599,22 @@ static JanetSlot janetc_call(JanetFopts opts, JanetSlot *slots, JanetSlot fun, c
|
||||
fun.constant, min, min == 1 ? "" : "s", min_arity);
|
||||
janetc_error(c, es);
|
||||
}
|
||||
if (structarg && ((min_arity - min) & 1)) {
|
||||
if (structarg && (min_arity > f->def->arity) && ((min_arity - f->def->arity) & 1)) {
|
||||
/* If we have an odd number of variadic arguments to a `&keys` function, that is almost certainly wrong. */
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL,
|
||||
"odd number of variadic arguments to `&keys` function %v", fun.constant);
|
||||
if (namedarg) {
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL,
|
||||
"odd number of named arguments to `&named` function %v", fun.constant);
|
||||
} else {
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL,
|
||||
"odd number of named arguments to `&keys` function %v", fun.constant);
|
||||
}
|
||||
}
|
||||
if (namedarg && f->def->named_args_count > 0) {
|
||||
/* For each argument passed in, check if it is one of the used named arguments
|
||||
* by checking the list defined in the function def. If not, raise a normal compiler
|
||||
* lint. We can also do a strict lint for _missing_ named arguments, although in many
|
||||
* cases those are assumed to have some kind of default, or we have dynamic keys. */
|
||||
int32_t first_arg_key_index = min + 1;
|
||||
int32_t first_arg_key_index = f->def->arity + 1;
|
||||
for (int32_t i = first_arg_key_index; i < janet_tuple_length(form); i += 2) {
|
||||
Janet argkey = form[i];
|
||||
/* Assumption: The first N constants of a function are its named argument keys. This
|
||||
|
||||
@@ -110,6 +110,9 @@
|
||||
(defn fnamed2 [_a _b _c &named x y z] [x y z])
|
||||
(defn fkeys2 [_a _b _c &keys ks] ks)
|
||||
(defn fnamed3 [{:x x} &named a b c] [x a b c])
|
||||
(defn fnamed4 [_y &opt _z &named a b c] [a b c])
|
||||
(defn fnamed5 [&opt _z &named a b c] [a b c])
|
||||
(defn g [x &opt y &named z] [x y z])
|
||||
|
||||
(defn check-good-compile
|
||||
[code msg]
|
||||
@@ -137,6 +140,15 @@
|
||||
(check-lint-compile '(fkeys2 nil nil nil :a 1 :b) "keys 2 odd args")
|
||||
(check-good-compile '(fnamed3 {:x 1} :a 1 :b 2 :c 3) "named 3 good")
|
||||
(check-lint-compile '(fnamed3 {:x 1} :a 1 :b 2 :d 3) "named 3 lint")
|
||||
(check-good-compile '(fnamed4 10 20 :a 1 :b 2 :c 3) "named 4 good")
|
||||
(check-lint-compile '(fnamed4 10 20 :a 1 :b 2 :d 3) "named 4 lint")
|
||||
(check-good-compile '(fnamed5 10 :a 1 :b 2 :c 3) "named 5 good")
|
||||
(check-lint-compile '(fnamed5 10 :a 1 :b 2 :d 3) "named 5 lint")
|
||||
(check-good-compile '(g 1) "g good 1")
|
||||
(check-good-compile '(g 1 2) "g good 2")
|
||||
(check-good-compile '(g 1 2 :z 10) "g good 3")
|
||||
(check-lint-compile '(g 1 2 :z) "g lint 1")
|
||||
(check-lint-compile '(g 1 2 :z 4 5) "g lint 2")
|
||||
|
||||
(end-suite)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user