Skip to content

feat(graindoc): Add bind information to errors #2263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 43 additions & 17 deletions compiler/graindoc/docblock.re
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,22 @@ exception
attr: string,
});

exception MissingLabeledParamType({name: string});
exception MissingUnlabeledParamType({idx: int});
exception
MissingLabeledParamType({
name: string,
bind_name: string,
});
exception
MissingUnlabeledParamType({
idx: int,
bind_name: string,
});
exception MissingReturnType;
exception AttributeAppearsMultipleTimes({attr: string});
exception
AttributeAppearsMultipleTimes({
attr: string,
bind_name: string,
});
exception
InvalidAttribute({
name: string,
Expand All @@ -116,30 +128,36 @@ let () =
attr,
);
Some(msg);
| MissingLabeledParamType({name}) =>
| MissingLabeledParamType({name, bind_name}) =>
let msg =
Printf.sprintf(
"Unable to find a matching function parameter for %s. Make sure a parameter exists with this label or use `@param <param_index> %s` for unlabeled parameters.",
"Unable to find a matching function parameter for `%s` on `%s`. Make sure a parameter exists with this label or use `@param <param_index> %s` for unlabeled parameters.",
name,
bind_name,
name,
);
Some(msg);
| MissingUnlabeledParamType({idx}) =>
| MissingUnlabeledParamType({idx, bind_name}) =>
let msg =
Printf.sprintf(
"Unable to find a type for parameter at index %d. Make sure a parameter exists at this index in the parameter list.",
"Unable to find a type for parameter at index `%d` on `%s`. Make sure a parameter exists at this index in the parameter list.",
idx,
bind_name,
);
Some(msg);
| MissingReturnType =>
let msg = "Unable to find a return type. Please file an issue!";
Some(msg);
| AttributeAppearsMultipleTimes({attr}) =>
| AttributeAppearsMultipleTimes({attr, bind_name}) =>
let msg =
Printf.sprintf("Attribute @%s is only allowed to appear once.", attr);
Printf.sprintf(
"Attribute `@%s` is only allowed to appear once on `%s`.",
attr,
bind_name,
);
Some(msg);
| InvalidAttribute({name, attr}) =>
let msg = Printf.sprintf("Invalid attribute @%s on %s", attr, name);
let msg = Printf.sprintf("Invalid attribute `@%s` on `%s`", attr, name);
Some(msg);
| _ => None
}
Expand Down Expand Up @@ -367,6 +385,7 @@ let for_value_description =
~lnum=loc.loc_start.pos_lnum - 1,
comments,
);
let bind_name = title_for_namepace(~module_namespace, name);

let (description, attributes) =
switch (comment) {
Expand Down Expand Up @@ -394,7 +413,8 @@ let for_value_description =
)
| Since({attr_version}) =>
switch (since) {
| Some(_) => raise(AttributeAppearsMultipleTimes({attr: "since"}))
| Some(_) =>
raise(AttributeAppearsMultipleTimes({attr: "since", bind_name}))
| None => (
deprecations,
Some({since_version: attr_version}),
Expand Down Expand Up @@ -423,7 +443,7 @@ let for_value_description =
string_of_int(idx),
Printtyp.string_of_type_sch(typ),
)
| None => raise(MissingUnlabeledParamType({idx: idx}))
| None => raise(MissingUnlabeledParamType({idx, bind_name}))
}
| LabeledParam(name) =>
switch (lookup_arg_by_label(name, args)) {
Expand All @@ -436,7 +456,7 @@ let for_value_description =
"?" ++ name,
Printtyp.string_of_type_sch(typ),
)
| _ => raise(MissingLabeledParamType({name: name}))
| _ => raise(MissingLabeledParamType({name, bind_name}))
}
};

Expand All @@ -452,7 +472,9 @@ let for_value_description =
| Returns({attr_desc: returns_msg}) =>
switch (returns) {
| Some(_) =>
raise(AttributeAppearsMultipleTimes({attr: "returns"}))
raise(
AttributeAppearsMultipleTimes({attr: "returns", bind_name}),
)
| None =>
let returns_type =
switch (return_type) {
Expand Down Expand Up @@ -520,6 +542,7 @@ let for_type_declaration =
~lnum=loc.loc_start.pos_lnum - 1,
comments,
);
let bind_name = title_for_namepace(~module_namespace, name);

let extract_compound_type_descrs = (datas, mk_type_descr) => {
List.map(
Expand All @@ -530,7 +553,7 @@ let for_type_declaration =
| Some((_, _, [attr, ..._])) =>
raise(
InvalidAttribute({
name: Format.asprintf("%a", Printtyp.ident, id),
name: Format.asprintf("%s.%a", bind_name, Printtyp.ident, id),
attr: attr_name(attr),
}),
)
Expand Down Expand Up @@ -591,7 +614,8 @@ let for_type_declaration =
)
| Since({attr_version}) =>
switch (since) {
| Some(_) => raise(AttributeAppearsMultipleTimes({attr: "since"}))
| Some(_) =>
raise(AttributeAppearsMultipleTimes({attr: "since", bind_name}))
| None => (
deprecations,
Some({since_version: attr_version}),
Expand Down Expand Up @@ -703,6 +727,7 @@ and for_signature_items =
~lnum=loc.loc_start.pos_lnum - 1,
comments,
);
let bind_name = title_for_namepace(~module_namespace, name);

let (description, attributes) =
switch (comment) {
Expand All @@ -722,7 +747,8 @@ and for_signature_items =
)
| Since({attr_version}) =>
switch (since) {
| Some(_) => raise(AttributeAppearsMultipleTimes({attr: "since"}))
| Some(_) =>
raise(AttributeAppearsMultipleTimes({attr: "since", bind_name}))
| None => (
deprecations,
Some({since_version: attr_version}),
Expand Down
10 changes: 10 additions & 0 deletions compiler/test/graindoc/invalidAttr.input.gr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module InvalidAttr

provide enum Invalid {
/**
* Value
*
* @param 0: This should fail
*/
InvalidVar,
}
9 changes: 9 additions & 0 deletions compiler/test/graindoc/missingLabeledParamType.input.gr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module MissingLabeledParam

/**
* This is a test function
*
* @param value: This should be val
*
*/
provide let missing = val => void
9 changes: 9 additions & 0 deletions compiler/test/graindoc/missingUnlabeledParamType.input.gr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module MissingUnlabeledParamType

/**
* This is a test function
*
* @param 0: This should be val
*
*/
provide let missing = () => void
22 changes: 20 additions & 2 deletions compiler/test/suites/graindoc.re
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,31 @@ describe("graindoc", ({test, testSkip}) => {
assertGrainDocError(
"singleSince",
"singleSince",
"Attribute @since is only allowed to appear once.",
"Attribute `@since` is only allowed to appear once on `SingleSince.test`.",
[|"--current-version=v0.2.0"|],
);
assertGrainDocError(
"singleReturn",
"singleReturn",
"Attribute @returns is only allowed to appear once.",
"Attribute `@returns` is only allowed to appear once on `SingleReturn.test`.",
[|"--current-version=v0.2.0"|],
);
assertGrainDocError(
"missingLabeledParam",
"missingLabeledParamType",
"Unable to find a matching function parameter for `value` on `MissingLabeledParam.missing`. Make sure a parameter exists with this label or use `@param <param_index> value` for unlabeled parameters.",
[|"--current-version=v0.2.0"|],
);
assertGrainDocError(
"missingUnlabeledParam",
"missingUnlabeledParamType",
"Unable to find a type for parameter at index `0` on `MissingUnlabeledParamType.missing`. Make sure a parameter exists at this index in the parameter list.",
[|"--current-version=v0.2.0"|],
);
assertGrainDocError(
"invalidAttr",
"invalidAttr",
"Invalid attribute `@param` on `InvalidAttr.Invalid.InvalidVar`",
[|"--current-version=v0.2.0"|],
);
});
Loading