diff --git a/plugin/__tests__/dependencies.spec.js b/plugin/__tests__/dependencies.spec.js index 9a9df862..13936b49 100644 --- a/plugin/__tests__/dependencies.spec.js +++ b/plugin/__tests__/dependencies.spec.js @@ -606,5 +606,100 @@ pluginTester({ ) ` }, + { + title: 'Should correctly detect dependencies from if else statements', + code: ` + import { View, Text } from 'react-native' + import { StyleSheet } from 'react-native-unistyles' + + export const Example = () => { + return ( + + Hello world + + ) + } + + const styles = StyleSheet.create((theme, rt) => ({ + container: someRandomInt => { + if (someRandomInt === 5) { + return { + backgroundColor: theme.colors.background + } + } + + if (someRandomInt === 10) { + return { + backgroundColor: theme.colors.barbie, + paddingBottom: rt.insets.bottom + } + } + + if (someRandomInt === 15) { + return { + fontSize: rt.fontScale * 10 + } + } else { + return { + backgroundColor: theme.colors.blood + } + } + } + })) + `, + output: ` + import { UnistylesShadowRegistry } from 'react-native-unistyles' + import { View, Text } from 'react-native' + import { StyleSheet } from 'react-native-unistyles' + + export const Example = () => { + return ( + { + UnistylesShadowRegistry.add(ref, [styles.container], undefined, [[5]]) + return () => UnistylesShadowRegistry.remove(ref) + }} + > + Hello world + + ) + } + + const styles = StyleSheet.create( + (theme, rt) => ({ + container: someRandomInt => { + if (someRandomInt === 5) { + return { + backgroundColor: theme.colors.background, + uni__dependencies: [0] + } + } + + if (someRandomInt === 10) { + return { + backgroundColor: theme.colors.barbie, + paddingBottom: rt.insets.bottom, + uni__dependencies: [0, 9] + } + } + + if (someRandomInt === 15) { + return { + fontSize: rt.fontScale * 10, + uni__dependencies: [11] + } + } else { + return { + backgroundColor: theme.colors.blood, + uni__dependencies: [0] + } + } + } + }), + 664955283 + ) + ` + }, ] }) diff --git a/plugin/index.js b/plugin/index.js index f979a9e2..6465be53 100644 --- a/plugin/index.js +++ b/plugin/index.js @@ -1,7 +1,7 @@ const addUnistylesImport = require('./import') const { getStyleMetadata, getStyleAttribute, styleAttributeToArray, handlePressable } = require('./style') const { getRefProp, addRef, overrideRef, hasStringRef } = require('./ref') -const { isUnistylesStyleSheet, analyzeDependencies, addStyleSheetTag, getUnistyle } = require('./stylesheet') +const { isUnistylesStyleSheet, analyzeDependencies, addStyleSheetTag, getUnistyles } = require('./stylesheet') const { isUsingVariants, extractVariants } = require('./variants') const reactNativeComponentNames = [ @@ -174,13 +174,11 @@ module.exports = function ({ types: t }) { if (t.isObjectExpression(arg)) { arg.properties.forEach(property => { if (t.isObjectProperty(property)) { - const propertyValue = getUnistyle(t, property) + const propertyValues = getUnistyles(t, property) - if (!propertyValue) { - return - } - - analyzeDependencies(t, state, property.key.name, propertyValue) + propertyValues.forEach(propertyValue => { + analyzeDependencies(t, state, property.key.name, propertyValue) + }) } }) } @@ -204,13 +202,11 @@ module.exports = function ({ types: t }) { if (t.isObjectExpression(body)) { body.properties.forEach(property => { if (t.isObjectProperty(property)) { - const propertyValue = getUnistyle(t, property) - - if (!propertyValue) { - return - } + const propertyValues = getUnistyles(t, property) - analyzeDependencies(t, state, property.key.name, propertyValue, themeLocalName, miniRuntimeLocalName) + propertyValues.forEach(propertyValue => { + analyzeDependencies(t, state, property.key.name, propertyValue, themeLocalName, miniRuntimeLocalName) + }) } }) } diff --git a/plugin/stylesheet.js b/plugin/stylesheet.js index fc43558e..fa341f4b 100644 --- a/plugin/stylesheet.js +++ b/plugin/stylesheet.js @@ -168,30 +168,45 @@ function analyzeDependencies(t, state, name, unistyleObj, themeName, rtName) { } } -function getUnistyle(t, property) { +function getUnistyles(t, property) { const propertyValue = t.isArrowFunctionExpression(property.value) ? property.value.body : property.value if (t.isObjectExpression(propertyValue)) { - return propertyValue + return [propertyValue] } if (t.isBlockStatement(propertyValue)) { - const returnStatement = propertyValue.body - .find(value => t.isReturnStatement(value)) - - return returnStatement - ? returnStatement.argument - : null + // here we might have single return statement + // or if-else statements with return statements + return propertyValue.body + .flatMap(value => { + if (t.isReturnStatement(value)) { + return [value] + } + + if (!t.isIfStatement(value)) { + return [] + } + + return [value.consequent, value.alternate] + .filter(Boolean) + .flatMap(value => { + if (t.isBlockStatement(value)) { + return value.body.filter(t.isReturnStatement) + } + }) + }) + .map(value => value.argument) } - return null + return [] } module.exports = { isUnistylesStyleSheet, analyzeDependencies, addStyleSheetTag, - getUnistyle + getUnistyles }