From bd69277bad70d5bf9c46ff9ccbeb3ff75407c6f4 Mon Sep 17 00:00:00 2001 From: zackad Date: Tue, 27 Aug 2024 09:47:03 +0700 Subject: [PATCH] refactor: make `key` on `ObjectProperty` type optional Close GH-58. ```twig {# keys can be omitted if it is the same as the variable name #} {foo} {# is equivalent to the following #} {'foo': foo} ``` Ref: https://twig.symfony.com/doc/3.x/templates.html#literals --- CHANGELOG.md | 5 ++++- src/melody/melody-parser/Parser.js | 4 ++-- src/melody/melody-types/index.js | 12 +++++------- src/print/ObjectProperty.js | 26 ++++++++++++++------------ 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fc37c7..0dbc182 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,15 @@ ## unreleased ### Features -- Add support for three-way-comparion operator (spaceship operator) +- Add support for three-way-comparison operator (spaceship operator) ### Bugfixes - Fix handling mapping that omit key part - Fix documentation about `twigAlwaysBreakObjects` option to reflect actual default value +### Internals +- Make `key` part of `ObjectProperty` type optional to support object declaration that omit key part + --- ## 0.8.0 (2024-08-09) diff --git a/src/melody/melody-parser/Parser.js b/src/melody/melody-parser/Parser.js index ba2cab1..9e24f49 100644 --- a/src/melody/melody-parser/Parser.js +++ b/src/melody/melody-parser/Parser.js @@ -791,13 +791,13 @@ export default class Parser { if (tokens.test(Types.COLON)) { tokens.expect(Types.COLON); const value = this.matchExpression(); - const prop = new n.ObjectProperty(key, value, computed); + const prop = new n.ObjectProperty(value, computed, key); copyStart(prop, key); copyEnd(prop, value); obj.properties.push(prop); } else { const value = key; - const prop = new n.ObjectProperty(key, value, computed, true); + const prop = new n.ObjectProperty(value, computed); copyStart(prop, key); copyEnd(prop, value); obj.properties.push(prop); diff --git a/src/melody/melody-types/index.js b/src/melody/melody-types/index.js index 4f911ba..b45b3cd 100644 --- a/src/melody/melody-types/index.js +++ b/src/melody/melody-types/index.js @@ -353,17 +353,15 @@ visitor(ObjectExpression, "properties"); export class ObjectProperty extends Node { /** - * @param {Node} key - * @param {Node} value - * @param {boolean} computed - * @param {boolean} omitKey + * @param {Node} value Actual object property value + * @param {boolean} computed Whether or not the Node require additional processing + * @param {Node|null} [key] Optional that would allow omitting key part */ - constructor(key, value, computed, omitKey = false) { + constructor(value, computed, key = null) { super(); - this.key = key; this.value = value; + this.key = key; this.computed = computed; - this.omitKey = omitKey; } } type(ObjectProperty, "ObjectProperty"); diff --git a/src/print/ObjectProperty.js b/src/print/ObjectProperty.js index 4c42383..2c17b91 100644 --- a/src/print/ObjectProperty.js +++ b/src/print/ObjectProperty.js @@ -6,21 +6,23 @@ const p = (node, path, print, options) => { !node.computed && Node.isStringLiteral(node.key) && !isValidIdentifierName(node.key.value); - const shouldPrintKeyAsString = node.key.wasImplicitConcatenation; + const shouldPrintKeyAsString = node.key?.wasImplicitConcatenation; const needsParentheses = node.computed && !shouldPrintKeyAsString; const parts = []; - if (needsParentheses) { - parts.push("("); - } - parts.push(path.call(print, "key")); - if (needsParentheses) { - parts.push(")"); - } - // handle property that omit key - if (node.omitKey) { - return parts; + + // print "key" part if they exist + if (node.key !== null) { + if (needsParentheses) { + parts.push("("); + } + parts.push(path.call(print, "key")); + if (needsParentheses) { + parts.push(")"); + } + parts.push(": "); } - parts.push(": "); + + // print "value" part node[STRING_NEEDS_QUOTES] = true; parts.push(path.call(print, "value")); return parts;