Skip to content

Commit 566e4d6

Browse files
committed
document exception analysis in editor-plugins
1 parent 27e2a40 commit 566e4d6

File tree

5 files changed

+93
-11
lines changed

5 files changed

+93
-11
lines changed

misc_docs/syntax/decorator_does_not_raise.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ category: "decorators"
77
status: "deprecated"
88
---
99

10-
> Deprecated since v12.0.0. Use the [@doesNotThrow](https://rescript-lang.org/syntax-lookup#does-not-throw-decorator) decorator instead.
10+
> Deprecated since v12.0.0. Use the [@doesNotThrow](/syntax-lookup#does-not-throw-decorator) decorator instead.
1111
12-
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](https://github.com/rescript-lang/reanalyze).
12+
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](/docs/manual/v12.0.0/editor-plugins#code-analysis).
1313
1414
`@doesNotRaise` is used to override the reanalyze's exception analysis and state that an expression does not throw any exceptions, even though the analysis reports otherwise. This can happen for example in the case of array access where the analysis does not perform range checks but takes a conservative stance that any access could potentially throw.
1515

1616
### References
1717

18-
- [Reanalyze: Exception Analysis](https://github.com/rescript-lang/reanalyze/blob/master/EXCEPTION.md)
18+
- [Reanalyze: Exception Analysis](/docs/manual/v12.0.0/editor-plugins#exception-analysis)

misc_docs/syntax/decorator_does_not_throw.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ summary: "This is the `@doesNotThrow` decorator."
66
category: "decorators"
77
---
88

9-
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](https://github.com/rescript-lang/reanalyze).
9+
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](/docs/manual/v12.0.0/editor-plugins#code-analysis).
1010
1111
`@doesNotThrow` is used to override the reanalyze's exception analysis and state that an expression does not throw any exceptions, even though the analysis reports otherwise. This can happen for example in the case of array access where the analysis does not perform range checks but takes a conservative stance that any access could potentially throw.
1212

1313
### References
1414

15-
- [Reanalyze: Exception Analysis](https://github.com/rescript-lang/reanalyze/blob/master/EXCEPTION.md)
15+
- [Reanalyze: Exception Analysis](/docs/manual/v12.0.0/editor-plugins#exception-analysis)

misc_docs/syntax/decorator_raises.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ category: "decorators"
77
status: "deprecated"
88
---
99

10-
> Deprecated since v12.0.0. Use the [@throws](https://rescript-lang.org/syntax-lookup#throws-decorator) decorator instead.
10+
> Deprecated since v12.0.0. Use the [@throws](/syntax-lookup#throws-decorator) decorator instead.
1111
12-
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](https://github.com/rescript-lang/reanalyze).
12+
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](/docs/manual/v12.0.0/editor-plugins#code-analysis).
1313
1414
`@raises` is picked up by reanalyze's exception analysis, and acknowledges that a function can throw exceptions that are not caught, and suppresses a warning in that case. Callers of the functions are then subjected to the same rule. Example `@raises(Exn)` or `@raises([E1, E2, E3])` for multiple exceptions.
1515

1616
### References
1717

18-
- [Reanalyze: Exception Analysis](https://github.com/rescript-lang/reanalyze/blob/master/EXCEPTION.md)
18+
- [Reanalyze: Exception Analysis](/docs/manual/v12.0.0/editor-plugins#exception-analysis)

misc_docs/syntax/decorator_throws.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ summary: "This is the `@throws` decorator."
66
category: "decorators"
77
---
88

9-
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](https://github.com/rescript-lang/reanalyze).
9+
> This decorator requires [`reanalyze`](https://github.com/rescript-lang/reanalyze), a code analysis tool for ReScript, to be installed. [Click here to read about how you get started with reanalyze.](/docs/manual/v12.0.0/editor-plugins#code-analysis).
1010
1111
`@throws` is picked up by reanalyze's exception analysis, and acknowledges that a function can throw exceptions that are not caught, and suppresses a warning in that case. Callers of the functions are then subjected to the same rule. Example `@throws(Exn)` or `@throws([E1, E2, E3])` for multiple exceptions.
1212

1313
### References
1414

15-
- [Reanalyze: Exception Analysis](https://github.com/rescript-lang/reanalyze/blob/master/EXCEPTION.md)
15+
- [Reanalyze: Exception Analysis](/docs/manual/v12.0.0/editor-plugins#exception-analysis)

pages/docs/manual/v12.0.0/editor-plugins.mdx

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,89 @@ The code analysis provides extra checks for your ReScript project, such as detec
4040
### Configuration
4141

4242
Add a `reanalyze` section to your `rescript.json` to control what the analyzer checks or ignores. You’ll get autocomplete for config options in the editor.
43-
More details: [reanalyze config docs](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson)
43+
More details: [reanalyze config docs](https://github.com/rescript-associlangation/reanalyze#configuration-via-bsconfigjson)
44+
45+
### Exception analysis
46+
47+
The exception analysis is designed to keep track statically of the exceptions that might be thrown at runtime. It works by issuing warnings and recognizing annotations. Warnings are issued whenever an exception is thrown and not immediately caught. Annotations are used to push warnings from he local point where the exception is thrown, to the outside context: callers of the current function.
48+
Nested functions need to be annotated separately.
49+
50+
Instructions on how to run the exception analysis using the `-exception` and `-exception-cmt` command-line arguments, or how to add `"analysis": ["exception"]` in `rescript.json` are contained in the [reanalyze config docs](https://github.com/rescript-associlangation/reanalyze#configuration-via-bsconfigjson).
51+
52+
Here's an example, where the analysis reports a warning any time an exception is thrown, and not caught:
53+
54+
```rescript
55+
let throws = () => throw(Not_found)
56+
```
57+
58+
reports:
59+
60+
```sh
61+
62+
Exception Analysis
63+
File "A.res", line 1, characters 4-10
64+
throws might throw Not_found (A.res:1:19) and is not annotated with @throws(Not_found)
65+
```
66+
67+
No warning is reported when a `@throws` annotation is added:
68+
69+
```rescript
70+
@throws(Not_found)
71+
let throws = () => throw(Not_found)
72+
```
73+
74+
When a function throws multiple exceptions, a tuple annotation is used:
75+
76+
77+
```rescript
78+
exception A
79+
exception B
80+
81+
@throws([A, B])
82+
let twoExceptions = (x, y) => {
83+
if (x) {
84+
throw(A)
85+
}
86+
if (y) {
87+
throw(B)
88+
}
89+
}
90+
```
91+
92+
It is possible to silence the analysis by adding a `@doesNotThrow` annotation:
93+
94+
```rescript
95+
@throws(Invalid_argument)
96+
let stringMake1 = String.make(12, ' ')
97+
98+
// Silence only the make function
99+
let stringMake2 = (@doesNotThrow String.make)(12, ' ')
100+
101+
// Silence the entire call (including arguments to make)
102+
let stringMake3 = @doesNotThrow String.make(12, ' ')
103+
104+
```
105+
106+
#### Limitations
107+
108+
- The libraries currently modeled are limited to `Array`, `Buffer`, `Bytes`, `Char`, `Filename`, `Hashtbl`, `List`, `Pervasives`, `Str`, `String` from the standard library, and `bs-json`, and `Json` from `Js`. Models are currently vendored in the analysis, and are easy to add (see [`src/ExnLib.ml`](src/ExnLib.ml))
109+
- Generic exceptions are not understood by the analysis. For example `exn` is not recognized below (only concrete exceptions are):
110+
111+
```rescript
112+
try (foo()) { | exn => throw(exn) }
113+
```
114+
115+
- Uses of e.g. `List.hd` are interpreted as belonging to the standard library. If you re-define `List` in the local scope, the analysis it will think it's dealing with `List` from the standard library.
116+
- There is no special support for functors. So with `Hashtbl.Make(...)` the builtin model will not apply. So the analysis won't report that the following can throw `Not_found`:
117+
118+
```rescript
119+
module StringHash =
120+
Hashtbl.Make({
121+
include String
122+
let hash = Hashtbl.hash
123+
})
124+
let specializedHash = tbl => StringHash.find(tbl, "abc")
125+
```
44126

45127
### Guide
46128

0 commit comments

Comments
 (0)