From 0879e5b5ef16e3e363f96412df6e1a921409ef5d Mon Sep 17 00:00:00 2001 From: Maija Heiskanen Date: Thu, 24 Nov 2022 10:54:05 +0200 Subject: [PATCH 1/2] Add test case for multiple spread operators --- tests/cases/spreadAttribute7.tsx | 1 + tests/references/spreadAttribute7.jsx | 12 ++++++++++++ tests/referencesES6/spreadAttribute7.jsx | 2 ++ 3 files changed, 15 insertions(+) create mode 100644 tests/cases/spreadAttribute7.tsx create mode 100644 tests/references/spreadAttribute7.jsx create mode 100644 tests/referencesES6/spreadAttribute7.jsx diff --git a/tests/cases/spreadAttribute7.tsx b/tests/cases/spreadAttribute7.tsx new file mode 100644 index 0000000..99856e5 --- /dev/null +++ b/tests/cases/spreadAttribute7.tsx @@ -0,0 +1 @@ +
; diff --git a/tests/references/spreadAttribute7.jsx b/tests/references/spreadAttribute7.jsx new file mode 100644 index 0000000..cd02957 --- /dev/null +++ b/tests/references/spreadAttribute7.jsx @@ -0,0 +1,12 @@ +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +import * as inferno from "inferno"; +var normalizeProps = inferno.normalizeProps; +var createVNode = inferno.createVNode; +normalizeProps(createVNode(1, "div", null, null, 1, __assign({}, props, other, more, { "foo": "bar" }))); diff --git a/tests/referencesES6/spreadAttribute7.jsx b/tests/referencesES6/spreadAttribute7.jsx new file mode 100644 index 0000000..c0a7a2f --- /dev/null +++ b/tests/referencesES6/spreadAttribute7.jsx @@ -0,0 +1,2 @@ +import { createVNode, normalizeProps } from "inferno"; +normalizeProps(createVNode(1, "div", null, null, 1, Object.assign({}, props, other, more, { "foo": "bar" }))); From 5b5e5b96d2de55f3b5c733fcaa52be93d909ae9a Mon Sep 17 00:00:00 2001 From: Maija Heiskanen Date: Mon, 28 Nov 2022 08:56:34 +0200 Subject: [PATCH 2/2] Keep the order of the props when using spread operator --- package.json | 4 ++-- src/index.ts | 27 ++++++++++++++++++------ tests/cases/spreadAttribute7.tsx | 2 +- tests/references/spreadAttribute5.jsx | 2 +- tests/references/spreadAttribute7.jsx | 2 +- tests/referencesES6/spreadAttribute5.jsx | 2 +- tests/referencesES6/spreadAttribute7.jsx | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 25b30d6..278a53a 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "inferno" ], "scripts": { - "test": "rimraf tests/temp && ts-node tests/index.ts", - "debug": "rimraf tests/temp && npm run build && node --inspect-brk --require ts-node/register tests/index.ts", + "test": "rimraf tests/temp && rimraf tests/tempES6 && ts-node tests/index.ts", + "debug": "rimraf tests/temp && rimraf tests/tempES6 && npm run build && node --inspect-brk --require ts-node/register tests/index.ts", "build": "tsc", "overwrite-references": "ts-node tests/overwriteReferences.ts", "prepublishOnly": "rimraf dist && tsc" diff --git a/src/index.ts b/src/index.ts index e441277..6974e5e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -478,7 +478,6 @@ export default () => { } function getVNodeProps(astProps: ts.NodeArray, isComponent) { - let props = [] let key = null let ref = null let className = null @@ -492,14 +491,28 @@ export default () => { let childFlags = null let contentEditable = false let assignArgs = [] + let propsPropertyAssignments = [] + let objectLiteralExpressionAdded = false for (let i = 0; i < astProps.length; i++) { let astProp = astProps[i] let initializer; if (astProp.kind === ts.SyntaxKind.JsxSpreadAttribute) { + if (propsPropertyAssignments.length) { + assignArgs.push(factory.createObjectLiteralExpression([...propsPropertyAssignments])) + + propsPropertyAssignments = [] + } + needsNormalization = true - assignArgs = [factory.createObjectLiteralExpression(), astProp.expression] + + if (!objectLiteralExpressionAdded) { + assignArgs.unshift(factory.createObjectLiteralExpression()) + objectLiteralExpressionAdded = true + } + + assignArgs.push(astProp.expression); } else { initializer = astProp.initializer let propName = astProp.name.text @@ -510,14 +523,14 @@ export default () => { ) { className = getValue(initializer, visitor) } else if (!isComponent && propName === 'htmlFor') { - props.push( + propsPropertyAssignments.push( factory.createPropertyAssignment( getName('for'), getValue(initializer, visitor) ) ) } else if (!isComponent && propName === 'onDoubleClick') { - props.push( + propsPropertyAssignments.push( factory.createPropertyAssignment( getName('onDblClick'), getValue(initializer, visitor) @@ -536,7 +549,7 @@ export default () => { ) } else if (!isComponent && propName in svgAttributes) { // React compatibility for SVG Attributes - props.push( + propsPropertyAssignments.push( factory.createPropertyAssignment( getName(svgAttributes[propName]), getValue(initializer, visitor) @@ -592,7 +605,7 @@ export default () => { if (propName.toLowerCase() === 'contenteditable') { contentEditable = true } - props.push( + propsPropertyAssignments.push( factory.createPropertyAssignment( getName(propName), initializer @@ -605,7 +618,7 @@ export default () => { } } - if (props.length) assignArgs.push(factory.createObjectLiteralExpression(props)) + if (propsPropertyAssignments.length) assignArgs.push(factory.createObjectLiteralExpression(propsPropertyAssignments)) return { props: assignArgs, diff --git a/tests/cases/spreadAttribute7.tsx b/tests/cases/spreadAttribute7.tsx index 99856e5..c9ec46b 100644 --- a/tests/cases/spreadAttribute7.tsx +++ b/tests/cases/spreadAttribute7.tsx @@ -1 +1 @@ -
; +
; diff --git a/tests/references/spreadAttribute5.jsx b/tests/references/spreadAttribute5.jsx index 50adaaf..c7556b7 100644 --- a/tests/references/spreadAttribute5.jsx +++ b/tests/references/spreadAttribute5.jsx @@ -9,4 +9,4 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { import * as inferno from "inferno"; var normalizeProps = inferno.normalizeProps; var createVNode = inferno.createVNode; -normalizeProps(createVNode(1, "div", "test", null, 1, __assign({}, props, { "foo": "bar" }))); +normalizeProps(createVNode(1, "div", "test", null, 1, __assign({}, { "foo": "bar" }, props))); diff --git a/tests/references/spreadAttribute7.jsx b/tests/references/spreadAttribute7.jsx index cd02957..f55b557 100644 --- a/tests/references/spreadAttribute7.jsx +++ b/tests/references/spreadAttribute7.jsx @@ -9,4 +9,4 @@ var __assign = (this && this.__assign) || Object.assign || function(t) { import * as inferno from "inferno"; var normalizeProps = inferno.normalizeProps; var createVNode = inferno.createVNode; -normalizeProps(createVNode(1, "div", null, null, 1, __assign({}, props, other, more, { "foo": "bar" }))); +normalizeProps(createVNode(1, "div", null, null, 1, __assign({}, props, other, { "foo": "bar", "foo2": "bar2" }, more, { "foo3": "bar3" }))); diff --git a/tests/referencesES6/spreadAttribute5.jsx b/tests/referencesES6/spreadAttribute5.jsx index 80ce0b3..dbce908 100644 --- a/tests/referencesES6/spreadAttribute5.jsx +++ b/tests/referencesES6/spreadAttribute5.jsx @@ -1,2 +1,2 @@ import { createVNode, normalizeProps } from "inferno"; -normalizeProps(createVNode(1, "div", "test", null, 1, Object.assign({}, props, { "foo": "bar" }))); +normalizeProps(createVNode(1, "div", "test", null, 1, Object.assign({}, { "foo": "bar" }, props))); diff --git a/tests/referencesES6/spreadAttribute7.jsx b/tests/referencesES6/spreadAttribute7.jsx index c0a7a2f..fdc1eee 100644 --- a/tests/referencesES6/spreadAttribute7.jsx +++ b/tests/referencesES6/spreadAttribute7.jsx @@ -1,2 +1,2 @@ import { createVNode, normalizeProps } from "inferno"; -normalizeProps(createVNode(1, "div", null, null, 1, Object.assign({}, props, other, more, { "foo": "bar" }))); +normalizeProps(createVNode(1, "div", null, null, 1, Object.assign({}, props, other, { "foo": "bar", "foo2": "bar2" }, more, { "foo3": "bar3" })));