mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Rewrite DreamChecker's readme
This commit is contained in:
parent
fba51ebb9a
commit
30b78983d0
1 changed files with 72 additions and 28 deletions
|
|
@ -1,37 +1,81 @@
|
|||
# DreamChecker
|
||||
|
||||
**DreamChecker** is a robust static analysis and typechecking engine for
|
||||
DreamMaker, the scripting language of the [BYOND] game engine.
|
||||
**DreamChecker** is a robust whole-program static analysis and type checking
|
||||
engine for DreamMaker, the scripting language of the [BYOND] game engine.
|
||||
|
||||
[BYOND]: https://secure.byond.com/
|
||||
|
||||
DreamMaker supports approximately four typechecking features:
|
||||
## Running DreamChecker
|
||||
|
||||
* Field and method use with `.` will compile error if the annotated type of the
|
||||
left-hand side does not have a field or method matching the name on the
|
||||
right-hand side. Replacing `.` with `:` bypasses this.
|
||||
* `for` loops where the automatically filter the input list using `istype` with
|
||||
the declared type of the loop variable, if present.
|
||||
* `new()` calls which omit the type to construct use the declared type of the
|
||||
left-hand side of an assignment in which they are involved.
|
||||
* `istype()` calls which omit the type to check against use the declared type
|
||||
of the variable passed to be checked.
|
||||
DreamChecker can be obtained with `cargo build -p dreamchecker` or from the
|
||||
[releases] page.
|
||||
|
||||
However, even this limited support has problems:
|
||||
DreamChecker should be run from within the DM project directory. It will
|
||||
automatically detect the `.dme` file, parse it, and issue diagnostics.
|
||||
DreamChecker will exit with a non-zero status code if it discovers any
|
||||
diagnostics, making it suitable for use in continuous integration environments.
|
||||
|
||||
* No way to specify the "value" type of associated lists, only the "key".
|
||||
* Typecasts of all kinds (up, down, sideways) have no syntax whatsoever and are
|
||||
wholly unchecked.
|
||||
* It is impossible to declare a return type for a procedure.
|
||||
* Various apparently typelike annotations have no compile- or run-time effects
|
||||
despite being accepted (and ignored) by the compiler.
|
||||
* There is no difference in type annotation between a variable intended to
|
||||
refer to object instances and typepaths. This leads to confusion, such as
|
||||
attempting to reference fields of a typepath as if it were an instance, which
|
||||
runtime errors.
|
||||
* There is no notion of nullable or non-nullable types.
|
||||
* There are no type annotations to represent primitives.
|
||||
[releases]: https://github.com/SpaceManiac/SpacemanDMM/releases
|
||||
|
||||
DreamChecker intends to address some or all of these shortcomings, integrating
|
||||
ideas from TypeScript and family, including flow typing and automatically
|
||||
determining appropriate type annotations in places where they are missing.
|
||||
## Diagnostics
|
||||
|
||||
In addition to the simple inline diagnostics discovered by the [parsing suite],
|
||||
DreamCheckers's whole-program analysis can find problems such as:
|
||||
|
||||
[parsing suite]: ../dreammaker/
|
||||
|
||||
* Unknown `set` setting names.
|
||||
* Undefined types on unused variables.
|
||||
* Keyword arguments being passed to procs which do not accept them.
|
||||
* Calling procs with non-keyword arguments following keyword arguments.
|
||||
* Proc overrides which are missing keyword arguments that their parents are
|
||||
called with.
|
||||
* Declaring vars with `/list` in unusual positions, e.g.
|
||||
`var/atom/list/movable/L`.
|
||||
* Use of `src` in global `/proc`s where it is guaranteed to be `null`.
|
||||
* Calling the parent proc `..()` when no such parent exists.
|
||||
* Accesses like `L[1].foo` and `foo().bar` wherein `.` acts like `:` instead.
|
||||
* List accesses perform lookups according to the type appended to `/list`,
|
||||
e.g. with `var/list/obj/L`, the type of `L[1]` will be `/obj` and a lookup
|
||||
of `L[1].name` will not generate a warning.
|
||||
* Proc calls will obey the [return type](#return-type) annotation if present.
|
||||
|
||||
## Extensions
|
||||
|
||||
DreamChecker also adds additional typing features to the language through a
|
||||
series of extensions, described below.
|
||||
Because DreamMaker does not recognize these extensions, it is recommended that
|
||||
you use the preprocessor flag `SPACEMAN_DMM` to determine whether they should
|
||||
be enabled:
|
||||
|
||||
```dm
|
||||
#ifdef SPACEMAN_DMM
|
||||
#define RETURN_TYPE(X) set SpacemanDMM_return_type = X
|
||||
#define SHOULD_CALL_PARENT(X) set SpacemanDMM_should_call_parent = X
|
||||
#else
|
||||
#define RETURN_TYPE(X)
|
||||
#define SHOULD_CALL_PARENT(X)
|
||||
#endif
|
||||
```
|
||||
|
||||
### Return type
|
||||
|
||||
Use `set SpacemanDMM_return_type = expression` to set a return type expression
|
||||
for a proc. The return type can take the forms:
|
||||
|
||||
* `/typepath` - a raw typepath. The return type of the proc is the type named.
|
||||
* `param` - a typepath given as a parameter, for procs which return an instance
|
||||
of the passed-in type.
|
||||
* `param.type` - the static type of a passed-in parameter, for procs which
|
||||
return their input or otherwise another value of the same type.
|
||||
* `param[_].type` - the static type of a passed-in parameter, with one level
|
||||
of `/list` stripped, for procs which select one item from a list. The `[_]`
|
||||
may be repeated to strip more levels of `/list`.
|
||||
|
||||
### Should call parent
|
||||
|
||||
Use `set SpacemanDMM_should_call_parent = 1` to enable a diagnostic on children
|
||||
of the proc it is set on which do not contain any `..()` parent calls. This can
|
||||
help with finding situations where a signal or other important handling in the
|
||||
parent proc is being skipped. Child procs may set this setting to `0` instead
|
||||
to override the check.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue