-
-
Notifications
You must be signed in to change notification settings - Fork 252
Syntax lookup for various decorators #177
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
Changes from 37 commits
8baa22d
4987d0a
f1f36e8
916b5d0
f288353
622dd12
dfe1cda
33a7370
46a97e8
1cb11a3
3557fa6
49a7b7d
55d7ff3
c5332f5
f9d4ea3
c5bd2f9
37ca04e
d60db1f
f24d471
f73643e
c674341
43b6e34
b6502fb
6f53ab3
ff5f05e
f424dd0
ae11d2a
3af0c98
00e08c8
ff60735
0f08e50
a225816
1218319
fc454f5
1c43255
5e51a46
e8c8ba0
520155f
2bb206e
6cc597e
037a8a1
bf26f7e
b5ece09
8de8283
3a2f7f4
0684575
98b316d
e248f6d
f634206
8d58c6c
c764884
0be5313
7598d86
3a779bf
43e81dc
1d02953
9be40cf
5141b49
f0bc375
97ddb3a
f8b7a78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,33 @@ | ||
--- | ||
test: "foo" | ||
id: "as-decorator" | ||
keywords: ["as", "decorator", "record", "field", "alias", "object"] | ||
name: "@as" | ||
summary: "This is the `@as` decorator." | ||
category: "decorators" | ||
--- | ||
|
||
Use this decorator on record types to alias record names to a different JS attribute name. | ||
The `@as` decorator may be used on record types to alias record field names to a different JavaScript attribute name. | ||
|
||
This is mostly useful to map to JS attribute names that cannot be expressed in ReScript (such as keywords). | ||
This is mostly useful to map to JavaScript attribute names that cannot be expressed in ReScript (such as keywords). | ||
|
||
### Example | ||
For example: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```reason | ||
```re | ||
type action = { | ||
[@bs.as "type"] _type: string, | ||
}; | ||
@as("type") type_: string | ||
} | ||
|
||
let action = {type_: "ADD_USER"} | ||
``` | ||
|
||
```js | ||
var action = { | ||
type: "ADD_USER" | ||
}; | ||
``` | ||
|
||
</CodeTab> | ||
|
||
Refer to the [Records as Objects](/docs/manual/latest/bind-to-js-object#bind-using-rescript-record) section for a more detailed explanation. | ||
It may also be used when declaring external [polymorphic variants](/docs/manual/latest/polymorphic-variant). See the `@string` and `@int` decorators for more details. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
--- | ||
id: "deriving-decorator" | ||
keywords: ["deriving", "decorator", "record", "variant"] | ||
name: "@deriving" | ||
summary: "This is the `@deriving` decorator." | ||
category: "decorators" | ||
--- | ||
|
||
The `@deriving(accessors)` decorator can be used to either: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are outdated examples and docs I believe.. The syntax discovery widget should be straight to the point, just point to related docs in a |
||
|
||
* Generate getter functions for a decorated **record** type, or | ||
* Generate creator functions for constructors of a **variant** type. | ||
|
||
The `@deriving(abstract)` decorator creates: | ||
|
||
* An abstract type representing the "abstract record". | ||
* A creator function for the new abstract type, where labeled arguments represent the attributes of the record. | ||
* A set of setter / getter functions for each record attribute | ||
|
||
Note that when using the `@deriving(abstract)` decorator, the original record type will be removed. | ||
You'll need to use the newly created functions to create / get / set values of this type. | ||
|
||
Example of **record** accessors: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
@deriving(accessors) | ||
type person = { | ||
name: string, | ||
age: int, | ||
} | ||
|
||
// This generates functions with signatures: | ||
// let name: (person) => string; | ||
// let age: (person) => int; | ||
|
||
let toString = (person): string => { | ||
name(person) ++ " " ++ Belt.Int.toString(age(person)) | ||
} | ||
|
||
let misha = { | ||
name: "Misha", | ||
age: 20, | ||
} | ||
|
||
let result = toString(misha) | ||
``` | ||
|
||
```js | ||
function name(param) { | ||
return param.name; | ||
} | ||
|
||
function age(param) { | ||
return param.age; | ||
} | ||
|
||
function toString(person) { | ||
return person.name + " " + String(person.age); | ||
} | ||
|
||
var misha = { | ||
name: "Misha", | ||
age: 20, | ||
}; | ||
|
||
var result = toString(misha); | ||
``` | ||
|
||
</CodeTab> | ||
|
||
Example of **variant** accessors: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
@deriving(accessors) | ||
type action = | ||
| SetName(string) | ||
| SetAge(int) | ||
| ClearAll | ||
|
||
// This generates functions with signatures: | ||
// let setName: (string) => action; | ||
// let age: (person) => int; | ||
|
||
let dispatch = action => { | ||
switch action { | ||
| SetName(name) => Js.log2("SetName", name) | ||
| SetAge(age) => Js.log2("SetAge", age) | ||
| ClearAll => Js.log("ClearAll") | ||
} | ||
} | ||
|
||
dispatch(setName("Hello")) | ||
dispatch(setAge(123)) | ||
dispatch(clearAll) | ||
``` | ||
|
||
```js | ||
function setName(param_0) { | ||
return { | ||
TAG: /* SetName */ 0, | ||
_0: param_0, | ||
} | ||
} | ||
|
||
function setAge(param_0) { | ||
return { | ||
TAG: /* SetAge */ 1, | ||
_0: param_0, | ||
} | ||
} | ||
|
||
function dispatch(action) { | ||
if (typeof action === "number") { | ||
console.log("ClearAll") | ||
return | ||
} | ||
if (action.TAG === /* SetName */ 0) { | ||
console.log("SetName", action._0) | ||
return | ||
} | ||
console.log("SetAge", action._0) | ||
} | ||
|
||
dispatch({ | ||
TAG: /* SetName */ 0, | ||
_0: "Hello", | ||
}) | ||
|
||
dispatch({ | ||
TAG: /* SetAge */ 1, | ||
_0: 123, | ||
}) | ||
|
||
dispatch(/* ClearAll */ 0) | ||
|
||
var clearAll = /* ClearAll */ 0 | ||
``` | ||
|
||
</CodeTab> | ||
|
||
Example of **abstract record** type: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
@deriving(abstract) | ||
type person = { | ||
name: string, | ||
mutable age: int, // Use the mutable keyword for generating setters | ||
} | ||
|
||
// Generates the following: | ||
// | ||
// An abstract type, replacing the original type: | ||
// | ||
// type person | ||
// | ||
// A type constructor: | ||
// | ||
// let person: (~name: string, ~age: int) => person | ||
// | ||
// Getters: | ||
// | ||
// let nameGet: (person) => string; | ||
// let ageGet: (person) => int | ||
// | ||
// Setters (only mutable attributes) | ||
// | ||
// let ageSet: (person, int) => unit | ||
|
||
let friend = person(~name="Misha", ~age=20) | ||
|
||
Js.log(friend->nameGet) // => "Misha" | ||
|
||
// Increase age by 1 via mutation | ||
friend->ageSet(friend->ageGet + 1) | ||
|
||
Js.log(friend->ageGet) // => 21 | ||
|
||
// This will NOT be possible (original type has been removed) | ||
// let misha = {name: "Misha", age: 20} | ||
|
||
``` | ||
|
||
```js | ||
var friend = { | ||
name: "Misha", | ||
age: 20 | ||
}; | ||
|
||
console.log(friend.name); | ||
|
||
friend.age = friend.age + 1 | 0; | ||
|
||
console.log(friend.age); | ||
``` | ||
|
||
</CodeTab> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
id: "get-decorator" | ||
keywords: ["get", "decorator", "property", "object", "bind"] | ||
name: "@get" | ||
summary: "This is the `@get` decorator." | ||
category: "decorators" | ||
--- | ||
|
||
The `@get` decorator is used to bind to a property of an object. | ||
|
||
For example: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
type element | ||
|
||
@scope("document") @val | ||
external createElement: string => element = "createElement" | ||
|
||
@get | ||
external getScrollTop: element => unit = "scrollTop" | ||
|
||
let div = createElement("div") | ||
let top = getScrollTop(div) | ||
``` | ||
|
||
```js | ||
var div = document.createElement("div") | ||
var top = div.scrollTop | ||
``` | ||
|
||
</CodeTab> | ||
|
||
|
||
kevanstannard marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
--- | ||
id: "get-index-decorator" | ||
keywords: ["get", "decorator", "array", "object", "index"] | ||
name: "@get_index" | ||
summary: "This is the `@get_index` decorator." | ||
category: "decorators" | ||
--- | ||
|
||
The `@get_index` decorator is used to access a dynamic property or index. | ||
|
||
For example with an Array: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
type t | ||
|
||
@new external create: int => t = "Array" | ||
@set_index external set: (t, int, string) => unit = "" | ||
@get_index external get: (t, int) => string = "" | ||
|
||
let a = create(3) | ||
a->set(0, "zero") | ||
a->set(1, "one") | ||
a->set(2, "two") | ||
|
||
let value = a->get(1) | ||
``` | ||
|
||
```js | ||
var a = new Array(3); | ||
|
||
a[0] = "zero"; | ||
a[1] = "one"; | ||
a[2] = "two"; | ||
|
||
var value = a[1]; | ||
``` | ||
|
||
</CodeTab> | ||
|
||
And an example with an object: | ||
|
||
<CodeTab labels={["ReScript", "JS Output"]}> | ||
|
||
```re | ||
type t | ||
|
||
@new external create: unit => t = "Object" | ||
@set_index external set: (t, string, int) => unit = "" | ||
@get_index external get: (t, string) => int = "" | ||
|
||
let o = create() | ||
o->set("x", 1) | ||
o->set("y", 3) | ||
o->set("z", 5) | ||
|
||
let value = o->get("y") | ||
``` | ||
|
||
```js | ||
var o = new Object(); | ||
|
||
o["x"] = 1; | ||
o["y"] = 3; | ||
o["z"] = 5; | ||
|
||
var value = o["y"]; | ||
``` | ||
|
||
</CodeTab> | ||
|
||
kevanstannard marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.