docs: add support for :override-doc in method declarations as well as documenting state handlers (#2139)

Adding support for better child-type method docstrings. This is a
problem unique to methods.

Usually, a child-type will have the same signature and a common name
will apply, but the implementation is different. This means, you
probably want a different docstring to describe what is happening.

Currently this is possible to do via `:replace`. The problem with
replace is two fold:
- a replaced method ends up in the generated `deftype`...because you
usually change the signature!
- we don't put docstrings in the `deftype` in normal GOAL, this is just
something we do for the `all-types` file (they go in the `defmethod`
instead)
- more importantly, this means anytime you now want to change the
parent's name/args/return type -- you have to apply that change
everywhere.

So this is a better design you can now just declare the method like so:
```clj
(:override-doc "my new docstring" <method_id>)
```

And internally a pseudo-replaced method will be added, but it will
inherit everything from the parent (except the docstring of course)

Unrelated - I also made all the keyword args for declaring methods not
depend on ordering

This also adds support for documenting virtual and non-virtual state
handlers. For example:

```clj
  (:states
    (part-tester-idle (:event "test") symbol))
```

or

```clj
(idle () _type_ :state (:event "test") 20)
```

I will probably add the ability to give some sort of over-view docstring
at a later date.

Co-authored-by: water <awaterford111445@gmail.com>
This commit is contained in:
Tyler Wilding
2023-01-21 20:45:45 -05:00
committed by GitHub
parent e5d6ac1c41
commit abf61a94fb
65 changed files with 793 additions and 472 deletions
+8 -6
View File
@@ -20,10 +20,11 @@ bool kind_for_lambda(FunctionName::FunctionKind k) {
bool try_convert_lambda(const Function& parent_function,
FormPool& pool,
Form* f,
bool defstate_behavior) {
bool defstate_behavior,
const DecompilerTypeSystem& dts) {
auto atom = form_as_atom(f);
if (atom && atom->is_static_addr()) {
auto lab = parent_function.ir2.env.file->labels.at(atom->label());
auto& lab = parent_function.ir2.env.file->labels.at(atom->label());
auto& env = parent_function.ir2.env;
const auto& info = parent_function.ir2.env.file->label_db->lookup(lab.name);
@@ -43,7 +44,7 @@ bool try_convert_lambda(const Function& parent_function,
}
goos::Object result;
if (defstate_behavior) {
result = final_output_defstate_anonymous_behavior(*other_func);
result = final_output_defstate_anonymous_behavior(*other_func, dts);
} else {
result = final_output_lambda(*other_func);
}
@@ -57,10 +58,11 @@ bool try_convert_lambda(const Function& parent_function,
}
} // namespace
// TODO - important entry point!
int insert_static_refs(Form* top_level_form,
FormPool& pool,
const Function& function,
const DecompilerTypeSystem&) {
const DecompilerTypeSystem& dts) {
int replaced = 0;
// first, look for defstates and lambdas to behaviors.
@@ -69,7 +71,7 @@ int insert_static_refs(Form* top_level_form,
if (as_defstate) {
for (auto& e : as_defstate->entries()) {
if (e.is_behavior) {
if (try_convert_lambda(function, pool, e.val, true)) {
if (try_convert_lambda(function, pool, e.val, true, dts)) {
replaced++;
}
}
@@ -79,7 +81,7 @@ int insert_static_refs(Form* top_level_form,
// next, all the rest.
top_level_form->apply_form([&](Form* f) {
if (try_convert_lambda(function, pool, f, false)) {
if (try_convert_lambda(function, pool, f, false, dts)) {
replaced++;
}
});