Skip to content

Commit

Permalink
Fix inline-plugin's Platform.select transform when used with ObjectMe…
Browse files Browse the repository at this point in the history
…thod

Summary:
Previously, metro was transforming `Platform.select` calls with ObjectMethod
properties into `undefined`.

This transforms these properties into named FunctionExpressions instead. I
believe this should preserve the original semantics.

Reviewed By: MichaReiser

Differential Revision: D25719371

fbshipit-source-id: 08473eee851b4e12ea753bc45595acec41363351
  • Loading branch information
bgw authored and facebook-github-bot committed Dec 30, 2020
1 parent 9b45643 commit 4d9908b
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,46 @@ describe('inline constants', () => {
});
});

it('inlines Platform.select in the code when using an ObjectMethod', () => {
const code = `
function a() {
var a = Platform.select({
ios() { return 1; },
async* android(a, b) { return 2; },
});
}
`;
const expected = `
function a() {
var a = async function*(a, b) { return 2; };
}
`;
compare([inlinePlugin], code, expected, {
inlinePlatform: 'true',
platform: 'android',
});
});

it('inlines Platform.select in the code when using an ObjectMethod with string keys', () => {
const code = `
function a() {
var a = Platform.select({
"ios"() { return 1; },
"android"() { return 2; },
});
}
`;
const expected = `
function a() {
var a = function() { return 2; };
}
`;
compare([inlinePlugin], code, expected, {
inlinePlatform: 'true',
platform: 'android',
});
});

it('does not inline Platform.select in the code when some of the properties are dynamic', () => {
const code = `
function a() {
Expand Down Expand Up @@ -340,6 +380,53 @@ describe('inline constants', () => {
});
});

it('does not inline Platform.select when ObjectMethod properties are dynamic', () => {
const code = `
function a() {
const COMPUTED_IOS = 'ios';
const COMPUTED_ANDROID = 'android';
var a = Platform.select({[COMPUTED_ANDROID]() {}, [COMPUTED_IOS]() {}});
}
`;

compare([inlinePlugin], code, code, {
inlinePlatform: true,
platform: 'android',
});
});

it('does not inline Platform.select when the object has a getter or setter', () => {
const code = `
function a() {
var a = Platform.select({
get ios() {},
get android() {},
});
}
`;

compare([inlinePlugin], code, code, {
inlinePlatform: true,
platform: 'android',
});
});

it('does not inline Platform.select when the object has a spread', () => {
const code = `
function a() {
var a = Platform.select({
...ios,
...android,
});
}
`;

compare([inlinePlugin], code, code, {
inlinePlatform: true,
platform: 'android',
});
});

it('does not inline Platform.select if it receives a non-object', () => {
const code = `
function a() {
Expand Down
20 changes: 14 additions & 6 deletions packages/metro-transform-plugins/src/inline-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ function inlinePlugin(
const {
isAssignmentExpression,
isIdentifier,
isStringLiteral,
isMemberExpression,
isObjectExpression,
isObjectMethod,
isObjectProperty,
isSpreadElement,
isObjectExpression,
isStringLiteral,
} = t;
const {isPlatformNode, isPlatformSelectNode} = createInlinePlatformChecks(
t,
Expand Down Expand Up @@ -99,16 +100,20 @@ function inlinePlugin(
let value = null;

for (const p of objectExpression.properties) {
if (!isObjectProperty(p)) {
if (!isObjectProperty(p) && !isObjectMethod(p)) {
continue;
}

if (
(isIdentifier(p.key) && p.key.name === key) ||
(isStringLiteral(p.key) && p.key.value === key)
) {
value = p.value;
break;
if (isObjectProperty(p)) {
value = p.value;
break;
} else if (isObjectMethod(p)) {
value = t.toExpression(p);
break;
}
}
}

Expand All @@ -120,6 +125,9 @@ function inlinePlugin(
if (p.computed || isSpreadElement(p)) {
return false;
}
if (isObjectMethod(p) && p.kind !== 'method') {
return false;
}

return isIdentifier(p.key) || isStringLiteral(p.key);
});
Expand Down

0 comments on commit 4d9908b

Please sign in to comment.