Skip to content

Commit

Permalink
Revert "Bug - shadow variable clash with destructured props (#1193)" (#…
Browse files Browse the repository at this point in the history
…1261)

* Revert "Bug - shadow variable clash with destructured props (#1193)"

This reverts commit 4f8f2aa.

* Add change set
  • Loading branch information
at-nathan committed Jul 13, 2022
1 parent d620362 commit 8912717
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 193 deletions.
5 changes: 5 additions & 0 deletions .changeset/modern-spiders-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@compiled/babel-plugin': patch
---

Revert "Bug - shadow variable clash with destructured props (#1193)"
Binary file not shown.
Binary file not shown.
75 changes: 38 additions & 37 deletions packages/babel-plugin/src/styled/__tests__/behaviour.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ describe('styled component behaviour', () => {
const _2 = \\"._bfhk1lco{background-color:var(--_kcgnsd)}\\";
const _ = \\"._bfhkhk3l{background-color:var(--_16ldrz5)}\\";
export const BadgeSkeleton = forwardRef(
({ as: C = \\"span\\", style, ...props }, ref) => (
({ as: C = \\"span\\", style, isLoading, loading: l, ...props }, ref) => (
<CC>
<CS>{[_, _2, _3, _4, _5, _6]}</CS>
<C
Expand All @@ -356,8 +356,8 @@ describe('styled component behaviour', () => {
ref={ref}
className={ax([
\\"\\",
props.isLoading ? \\"_bfhkhk3l\\" : \\"_bfhk1lco\\",
props.loading ? \\"_syaz1c44\\" : \\"_syazs2l2\\",
isLoading ? \\"_bfhkhk3l\\" : \\"_bfhk1lco\\",
l ? \\"_syaz1c44\\" : \\"_syazs2l2\\",
propz.loading ? \\"_1h6d1c5w\\" : \\"_1h6d1qzc\\",
props.className,
])}
Expand Down Expand Up @@ -427,6 +427,7 @@ describe('styled component behaviour', () => {
padding: 8px;
\`;
`);

expect(actual).toIncludeMultiple([
'._syaz5scu{color:red}',
'._syaz13q2{color:blue}',
Expand All @@ -440,7 +441,7 @@ describe('styled component behaviour', () => {
'._ca0qftgi{padding-top:8px}',
'._19itlf8h{border:2px solid blue}',
'._1wyb1ul9{font-size:30px}',
'ax(["_1wyb1ul9 _19itlf8h _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi",props.isPrimary?"_syaz13q2":"_syaz5scu",props.isDone?"_1hms1911":"_1hmsglyw",props.isClamped?"_1yyj11wp":"_1yyjkb7n",props.className])',
'ax(["_1wyb1ul9 _19itlf8h _ca0qftgi _u5f3ftgi _n3tdftgi _19bvftgi",props.isPrimary?"_syaz13q2":"_syaz5scu",isDone?"_1hms1911":"_1hmsglyw",isClamped?"_1yyj11wp":"_1yyjkb7n",props.className])',
]);
});

Expand Down Expand Up @@ -478,7 +479,7 @@ describe('styled component behaviour', () => {
'._18u019bv{margin-left:10px}',
'._2hwx14y2{margin-right:5px}',
'._2hwx19bv{margin-right:10px}',
'ax(["",props.isPrimary?"_syaz13q2":"_syaz5scu",props.isLast?"_18u014y2":"_18u019bv",props.isLast?"_2hwx14y2":"_2hwx19bv",props.className])',
'ax(["",props.isPrimary?"_syaz13q2":"_syaz5scu",isLast?"_18u014y2":"_18u019bv",isLast?"_2hwx14y2":"_2hwx19bv",props.className])',
]);
});

Expand Down Expand Up @@ -528,9 +529,9 @@ describe('styled component behaviour', () => {

expect(actual).toIncludeMultiple([
'._1bsb1osq{width:100%}',
'._1bsb18ks{width:var(--_1w7p4it)}',
'style={{...style,"--_1w7p4it":ix(props.CUSTOM_WIDTH,"px")}}',
`ax(["",props.useCustomWidth?"_1bsb18ks":"_1bsb1osq",props.className])`,
'._1bsby2bc{width:var(--_znisgh)}',
'style={{...style,"--_znisgh":ix(CUSTOM_WIDTH,"px")}}',
`ax([\"\",useCustomWidth?\"_1bsby2bc\":\"_1bsb1osq\",props.className])`,
]);
});

Expand All @@ -545,9 +546,9 @@ describe('styled component behaviour', () => {

expect(actual).toIncludeMultiple([
'._1bsb1osq{width:100%}',
'._1bsb1exv{width:var(--_jvf4nj)}',
'--_jvf4nj":ix(props.size.width,"px"',
'ax(["",props.size.width?"_1bsb1exv":"_1bsb1osq",props.className]',
'._1bsb9tg7{width:var(--_1ea5ebz)}',
'--_1ea5ebz":ix(width,"px"',
'ax(["",width?"_1bsb9tg7":"_1bsb1osq",props.className]',
]);
});

Expand All @@ -562,9 +563,9 @@ describe('styled component behaviour', () => {

expect(actual).toIncludeMultiple([
'._1bsb1osq{width:100%}',
'"._1bsbvfya{width:var(--_4qc1aa)}',
'--_4qc1aa":ix(props.elementWidth,"px")',
'ax(["",props.elementWidth?"_1bsbvfya":"_1bsb1osq",props.className])',
'"._1bsb9tg7{width:var(--_1ea5ebz)}',
'--_1ea5ebz":ix(width,"px")',
'ax(["",width?"_1bsb9tg7":"_1bsb1osq",props.className])',
]);
});

Expand Down Expand Up @@ -637,11 +638,11 @@ describe('styled component behaviour', () => {
`);

expect(actual).toIncludeMultiple([
'{as:C="div",style,...props},ref)',
'{as:C="div",style,width,...props}',
'._1bsb1osq{width:100%}',
'._1bsb17ei{width:var(--_1fymg38)}',
'"--_1fymg38":ix(props.width,"px")',
'className={ax(["",props.width?"_1bsb17ei":"_1bsb1osq",props.className])}',
'._1bsb9tg7{width:var(--_1ea5ebz)}',
'"--_1ea5ebz":ix(width,"px")',
'className={ax(["",width?"_1bsb9tg7":"_1bsb1osq",props.className])}',
]);
});

Expand All @@ -655,10 +656,10 @@ describe('styled component behaviour', () => {
`);

expect(actual).toIncludeMultiple([
'{as:C="div",style,...props},ref)',
'_1bsbwitj{width:var(--_1fymg38))}',
'"--_1fymg38":ix(props.width,"px")',
'className={ax(["",props.width&&"_1bsbwitj",props.className])}',
'{as:C="div",style,width,...props}',
'._1bsb1r3a{width:var(--_1ea5ebz))}',
'"--_1ea5ebz":ix(width,"px")',
'className={ax(["",width&&"_1bsb1r3a",props.className])}',
]);
});

Expand Down Expand Up @@ -1165,9 +1166,9 @@ describe('styled component behaviour', () => {
`);

expect(actual).toIncludeMultiple([
'_1bsb16om{width:calc(10px + var(--_13fw46q))}',
'"--_13fw46q":ix(isLarge?100:50,"px")',
'{ax(["_1bsb16om",props.className])}',
'._1bsb60qm{width:calc(10px + var(--_15nkcot))}',
'"--_15nkcot":ix(isLarge?100:50,"px")',
'{ax(["_1bsb60qm",props.className])}',
]);
});

Expand All @@ -1182,9 +1183,9 @@ describe('styled component behaviour', () => {
`);

expect(actual).toIncludeMultiple([
'._1bsb1k9r{width:calc(var(--_13fw46q) - 10px)}',
'"--_13fw46q":ix(isLarge?100:50,"px")',
'{ax(["_1bsb1k9r",props.className])}',
'._1bsb1j3u{width:calc(var(--_15nkcot) - 10px)}',
'"--_15nkcot":ix(isLarge?100:50,"px")',
'{ax(["_1bsb1j3u",props.className])}',
]);
});

Expand All @@ -1200,9 +1201,9 @@ describe('styled component behaviour', () => {
`);

expect(actual).toIncludeMultiple([
'._1kt914bl:before{content:var(--_5jcge)}',
"--_5jcge\":ix(isOpen?'show less':'show more'",
'ax(["_1kt914bl",props.className])}',
'._1kt9x4xj:before{content:var(--_1boodpz)}',
'"--_1boodpz":ix(isOpen?\'show less\':\'show more\',"\'","\'")',
'{ax(["_1kt9x4xj",props.className])}',
]);
});

Expand All @@ -1226,7 +1227,7 @@ describe('styled component behaviour', () => {
'._syaz1gy6{color:yellow}',
'._bfw71j9v:hover{border:1px solid white}',
'_bfw7l468:hover{border:2px solid black}',
'{ax(["_11q7qm1v",props.isSelected?"_syaz13q2":"_syaz1gy6",props.isHover?"_bfw71j9v":"_bfw7l468",props.className])}',
'{ax(["_11q7qm1v",isSelected?"_syaz13q2":"_syaz1gy6",isHover?"_bfw71j9v":"_bfw7l468",props.className])}',
]);
});

Expand All @@ -1247,7 +1248,7 @@ describe('styled component behaviour', () => {
'._syaz1gy6{color:yellow}',
'._bfw71j9v:hover{border:1px solid white}',
'_bfw7l468:hover{border:2px solid black}',
'{ax(["",props.isSelected?"_syaz13q2":"_syaz1gy6",props.isHover?"_bfw71j9v":"_bfw7l468",props.className])}',
'{ax(["",isSelected?"_syaz13q2":"_syaz1gy6",isHover?"_bfw71j9v":"_bfw7l468",props.className])}',
]);
});

Expand Down Expand Up @@ -1279,7 +1280,7 @@ describe('styled component behaviour', () => {
'._vw871qok:hover:before{content:\\"Don\'t break closure parsing }\\"}',
'._1jly1kw7:hover:before{display:inherit}',
'._1jly1nu9:hover:before{display:inline}',
'{ax(["_irr31i1c _vw871qok",props.isSelected?"_syaz13q2":"_syaz1gy6",props.isHover?"_bfw71j9v":"_bfw7l468",props.isBefore?"_1jly1kw7":"_1jly1nu9",props.className])}',
'{ax(["_irr31i1c _vw871qok",isSelected?"_syaz13q2":"_syaz1gy6",isHover?"_bfw71j9v":"_bfw7l468",isBefore?"_1jly1kw7":"_1jly1nu9",props.className])}',
]);
});

Expand Down Expand Up @@ -1307,7 +1308,7 @@ describe('styled component behaviour', () => {
'._irr31i1c:hover{background-color:cyan}',
'._vn891l7b:focus{border-radius:3px}',
'._vn89yh40:focus{border-radius:2px}',
'{ax(["_1oey5scu _irr31i1c",props.isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
'{ax(["_1oey5scu _irr31i1c",isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
]);
});

Expand Down Expand Up @@ -1335,7 +1336,7 @@ describe('styled component behaviour', () => {
'._irr31i1c:hover{background-color:cyan}',
'._vn891l7b:focus{border-radius:3px}',
'._vn89yh40:focus{border-radius:2px}',
'{ax(["_1oey5scu _irr31i1c",props.isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
'{ax(["_1oey5scu _irr31i1c",isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
]);
});

Expand Down Expand Up @@ -1363,7 +1364,7 @@ describe('styled component behaviour', () => {
'._irr31i1c:hover{background-color:cyan}',
'._vn891l7b:focus{border-radius:3px}',
'._vn89yh40:focus{border-radius:2px}',
'{ax(["_1oey5scu _irr31i1c",props.isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
'{ax(["_1oey5scu _irr31i1c",isFocus?"_vn891l7b":"_vn89yh40",props.className])}',
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,6 @@ describe('styled object call expression', () => {
});
`);

expect(actual).toInclude('{ as: C = "span", style, ...props }');
expect(actual).toInclude('{ as: C = "span", style, isLoading, loading: l, ...props }');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ describe('styled tagged template expression', () => {

expect(actual).toIncludeMultiple([
'isLoading ? colors.N20 : colors.N40',
'props.loading ? colors.N50 : colors.N10',
'l ? colors.N50 : colors.N10',
'props.loading ? colors.N100 : colors.N200',
]);
});
Expand All @@ -827,7 +827,7 @@ describe('styled tagged template expression', () => {
\`;
`);

expect(actual).toInclude('{ as: C = "span", style, ...props }');
expect(actual).toInclude('{ as: C = "span", style, isLoading, loading: l, ...props }');
});

it('should place classes in given order when static styles precede expression', () => {
Expand Down
130 changes: 1 addition & 129 deletions packages/babel-plugin/src/utils/css-builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import type {
LogicalCssItem,
SheetCssItem,
PartialBindingWithMeta,
FunctionParameters,
} from './types';

/**
Expand Down Expand Up @@ -527,7 +526,7 @@ const extractObjectExpression = (node: t.ObjectExpression, meta: Metadata): CSSO
Given statments like:
fontWeight: (props) => props.isBold ? 'bold': 'normal',
marginTop: (props) => `${props.isLast ? 5 : 10}px`,
Convert them to:
`font-weight: ${(props) => props.isBold ? 'bold': 'normal'};`
Expand Down Expand Up @@ -620,126 +619,6 @@ const extractObjectExpression = (node: t.ObjectExpression, meta: Metadata): CSSO
return { css: mergeSubsequentUnconditionalCssItems(css), variables };
};

/**
* Creates and returns `props` object
*
* @param deconstructedProp deconstructed prop
* @param parameters Group of parameters from deconstructed props
* @param prevKey to store keys of nested deconstructed props
*/
const getPropsNotDestructured = (
deconstructedProp: string,
parameters: FunctionParameters[],
prevKey?: string
): string => {
for (const param of parameters) {
if (Array.isArray(param.value)) {
prevKey = param.key + '.';
getPropsNotDestructured(deconstructedProp, param.value, prevKey);
}

/**
* Deconstructed props may have alias and alias is used throughout the function.
* Prop is treated as `key` and alias as `value`.
* So we have to find the `value` and replace it with `key`.
*
* For eg:
* ({isPrimary: primary}) => primary ? 'green' : 'red'
*
* The above code has to be converted into:
* (props) => props.isPrimary ? 'green' : 'red'
*/
const parameter = parameters.find((x) => x.value == deconstructedProp);
if (parameter) {
return prevKey ? prevKey + parameter.key : parameter.key;
}
}

return prevKey ? prevKey + deconstructedProp : deconstructedProp;
};
/**
* Generates array of parameters from deconstructed `props`
*
* @param node ArrowFunction that has deconstructed `props` as parameters
* @returns Array of parameters
*/
const getParametersFromDestructuredProps = (
node: t.ObjectPattern,
meta: Metadata
): FunctionParameters[] => {
let parameters: FunctionParameters[] = [];
const properties = node.properties;
parameters = properties
.map((po) => {
if (t.isObjectProperty(po)) {
const params: FunctionParameters = {
key: getKey(po.key, meta),
value: t.isObjectPattern(po.value)
? getParametersFromDestructuredProps(po.value, meta)
: getKey(po.value as t.Expression, meta),
};
return params;
}
return;
})
.filter(Boolean) as FunctionParameters[];
return parameters;
};

/**
* Convert `consequent` and `alternate` of Conditional expressions into Member Expression
* @param node Expression which has to be converted into Member Expression
* @param parameters Deconstructed props
*/
const modifyTemplateLiterals = (node: t.Expression, parameters: FunctionParameters[]) => {
if (t.isTemplateLiteral(node) && t.isIdentifier(node.expressions[0])) {
const notDestructuredProps = getPropsNotDestructured(node.expressions[0].name, parameters);
node.expressions[0] = t.memberExpression(
t.identifier('props'),
t.identifier(notDestructuredProps)
);
}
};

/**
* Babel was not able to differentiate between destructed prop and global variable if they have same name,
* resulting in global variable being applied instead.
* Prevent shadow variables to clash with destructured props by reconstructing props.
*
* For example, given:
* ```
* const isPrimary = true;
* const Component = styled.div`
* color: ${({ isPrimary }) => (isPrimary ? 'green' : 'red')};
* `;
*```
* it will be converted to
* ```
* const Component = styled.div`
* color: ${(props) => (props.isPrimary ? 'green' : 'red')};
* * `;
* ```
* to avoid name clash
*
* @param node Node we're interested in extracting props from.
*/
const reconstructDestructedProps = (node: t.ArrowFunctionExpression, meta: Metadata) => {
const parameters = getParametersFromDestructuredProps(node.params[0] as t.ObjectPattern, meta);

if (t.isConditionalExpression(node.body)) {
if (t.isIdentifier(node.body.test)) {
const notDestructuredProps = getPropsNotDestructured(node.body.test.name, parameters);
node.params[0] = t.identifier('props');
node.body.test = t.memberExpression(
t.identifier('props'),
t.identifier(notDestructuredProps)
);
}
modifyTemplateLiterals(node.body.consequent, parameters);
modifyTemplateLiterals(node.body.alternate, parameters);
}
};

/**
* Extracts CSS data from a template literal node.
*
Expand All @@ -754,13 +633,6 @@ const extractTemplateLiteral = (node: t.TemplateLiteral, meta: Metadata): CSSOut
const literalResult = node.quasis.reduce<string>((acc, quasi, index): string => {
const nodeExpression = node.expressions[index] as t.Expression | undefined;

if (
t.isArrowFunctionExpression(nodeExpression) &&
t.isObjectPattern(nodeExpression.params[0])
) {
reconstructDestructedProps(nodeExpression, meta);
}

if (
!nodeExpression ||
(t.isArrowFunctionExpression(nodeExpression) && t.isLogicalExpression(nodeExpression.body))
Expand Down

0 comments on commit 8912717

Please sign in to comment.