KCL: Object literals like {x} as shorthand for {x: x} (#4521)
If the key and value in an object literal use the same identifier, allow abbreviating it.
Basically these two are now equivalent:
```
x = 2
obj = { x: x, y: 3}
```
```diff
x = 2
- obj = { x: x, y: 3}
+ obj = { x, y: 3}
```
This syntax is used in JS, Rust and probably elsewhere too.
Here's a more realistic example. Before:
```
radius = 10
startSketchAt([0, 0])
|> circle({center: [0, 0], radius: radius}, %)
```
After:
```diff
radius = 10
startSketchAt([0, 0])
- |> circle({center: [0, 0], radius: radius}, %)
+ |> circle({center: [0, 0], radius}, %)
```
This commit is contained in:
@ -596,6 +596,21 @@ fn array_end_start(i: TokenSlice) -> PResult<Node<ArrayRangeExpression>> {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn object_property_same_key_and_val(i: TokenSlice) -> PResult<Node<ObjectProperty>> {
|
||||||
|
let key = identifier.context(expected("the property's key (the name or identifier of the property), e.g. in 'height: 4', 'height' is the property key")).parse_next(i)?;
|
||||||
|
ignore_whitespace(i);
|
||||||
|
Ok(Node {
|
||||||
|
start: key.start,
|
||||||
|
end: key.end,
|
||||||
|
module_id: key.module_id,
|
||||||
|
inner: ObjectProperty {
|
||||||
|
value: Expr::Identifier(Box::new(key.clone())),
|
||||||
|
key,
|
||||||
|
digest: None,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn object_property(i: TokenSlice) -> PResult<Node<ObjectProperty>> {
|
fn object_property(i: TokenSlice) -> PResult<Node<ObjectProperty>> {
|
||||||
let key = identifier.context(expected("the property's key (the name or identifier of the property), e.g. in 'height: 4', 'height' is the property key")).parse_next(i)?;
|
let key = identifier.context(expected("the property's key (the name or identifier of the property), e.g. in 'height: 4', 'height' is the property key")).parse_next(i)?;
|
||||||
ignore_whitespace(i);
|
ignore_whitespace(i);
|
||||||
@ -642,7 +657,11 @@ pub(crate) fn object(i: TokenSlice) -> PResult<Node<ObjectExpression>> {
|
|||||||
0..,
|
0..,
|
||||||
alt((
|
alt((
|
||||||
terminated(non_code_node.map(NonCodeOr::NonCode), whitespace),
|
terminated(non_code_node.map(NonCodeOr::NonCode), whitespace),
|
||||||
terminated(object_property, property_separator).map(NonCodeOr::Code),
|
terminated(
|
||||||
|
alt((object_property, object_property_same_key_and_val)),
|
||||||
|
property_separator,
|
||||||
|
)
|
||||||
|
.map(NonCodeOr::Code),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.context(expected(
|
.context(expected(
|
||||||
@ -3888,6 +3907,11 @@ const my14 = 4 ^ 2 - 3 ^ 2 * 2
|
|||||||
snapshot_test!(bf, "let x = 3 != 3");
|
snapshot_test!(bf, "let x = 3 != 3");
|
||||||
snapshot_test!(bg, r#"x = 4"#);
|
snapshot_test!(bg, r#"x = 4"#);
|
||||||
snapshot_test!(bh, "const obj = {center : [10, 10], radius: 5}");
|
snapshot_test!(bh, "const obj = {center : [10, 10], radius: 5}");
|
||||||
|
snapshot_test!(
|
||||||
|
bi,
|
||||||
|
r#"x = 3
|
||||||
|
obj = { x, y: 4}"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|||||||
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
source: kcl/src/parser/parser_impl.rs
|
||||||
|
expression: actual
|
||||||
|
snapshot_kind: text
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"end": 5,
|
||||||
|
"id": {
|
||||||
|
"end": 1,
|
||||||
|
"name": "x",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"end": 5,
|
||||||
|
"raw": "3",
|
||||||
|
"start": 4,
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"value": 3
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclarator"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"end": 5,
|
||||||
|
"kind": "const",
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"end": 30,
|
||||||
|
"id": {
|
||||||
|
"end": 17,
|
||||||
|
"name": "obj",
|
||||||
|
"start": 14,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"end": 30,
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"end": 23,
|
||||||
|
"key": {
|
||||||
|
"end": 23,
|
||||||
|
"name": "x",
|
||||||
|
"start": 22,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"start": 22,
|
||||||
|
"type": "ObjectProperty",
|
||||||
|
"value": {
|
||||||
|
"end": 23,
|
||||||
|
"name": "x",
|
||||||
|
"start": 22,
|
||||||
|
"type": "Identifier",
|
||||||
|
"type": "Identifier"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"end": 29,
|
||||||
|
"key": {
|
||||||
|
"end": 26,
|
||||||
|
"name": "y",
|
||||||
|
"start": 25,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"start": 25,
|
||||||
|
"type": "ObjectProperty",
|
||||||
|
"value": {
|
||||||
|
"end": 29,
|
||||||
|
"raw": "4",
|
||||||
|
"start": 28,
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"value": 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start": 20,
|
||||||
|
"type": "ObjectExpression",
|
||||||
|
"type": "ObjectExpression"
|
||||||
|
},
|
||||||
|
"start": 14,
|
||||||
|
"type": "VariableDeclarator"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"end": 30,
|
||||||
|
"kind": "const",
|
||||||
|
"start": 14,
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"end": 30,
|
||||||
|
"start": 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user