mirror of https://github.com/status-im/metro.git
Extract some platform related code to a separate file
Reviewed By: davidaurelio Differential Revision: D6491060 fbshipit-source-id: e8d040495b549e1925932b4ded4b44dd1f81fff6
This commit is contained in:
parent
db47372f06
commit
1a37164dac
|
@ -0,0 +1,104 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2016-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const babel = require('babel-core');
|
||||||
|
|
||||||
|
const t = babel.types;
|
||||||
|
const importMap = new Map([['ReactNative', 'react-native']]);
|
||||||
|
|
||||||
|
const isPlatformOS = (node: any, scope: any, isWrappedModule: boolean) =>
|
||||||
|
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||||
|
isImportOrGlobal(node.object, scope, [{name: 'Platform'}], isWrappedModule);
|
||||||
|
|
||||||
|
const isReactPlatformOS = (node: any, scope: any, isWrappedModule: boolean) =>
|
||||||
|
t.isIdentifier(node.property, {name: 'OS'}) &&
|
||||||
|
t.isMemberExpression(node.object) &&
|
||||||
|
t.isIdentifier(node.object.property, {name: 'Platform'}) &&
|
||||||
|
isImportOrGlobal(
|
||||||
|
node.object.object,
|
||||||
|
scope,
|
||||||
|
[{name: 'React'}, {name: 'ReactNative'}],
|
||||||
|
isWrappedModule,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isPlatformSelect = (node: any, scope: any, isWrappedModule: boolean) =>
|
||||||
|
t.isMemberExpression(node.callee) &&
|
||||||
|
t.isIdentifier(node.callee.object, {name: 'Platform'}) &&
|
||||||
|
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||||
|
isImportOrGlobal(
|
||||||
|
node.callee.object,
|
||||||
|
scope,
|
||||||
|
[{name: 'Platform'}],
|
||||||
|
isWrappedModule,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isReactPlatformSelect = (
|
||||||
|
node: any,
|
||||||
|
scope: any,
|
||||||
|
isWrappedModule: boolean,
|
||||||
|
) =>
|
||||||
|
t.isMemberExpression(node.callee) &&
|
||||||
|
t.isIdentifier(node.callee.property, {name: 'select'}) &&
|
||||||
|
t.isMemberExpression(node.callee.object) &&
|
||||||
|
t.isIdentifier(node.callee.object.property, {name: 'Platform'}) &&
|
||||||
|
isImportOrGlobal(
|
||||||
|
node.callee.object.object,
|
||||||
|
scope,
|
||||||
|
[{name: 'React'}, {name: 'ReactNative'}],
|
||||||
|
isWrappedModule,
|
||||||
|
);
|
||||||
|
|
||||||
|
const isGlobal = binding => !binding;
|
||||||
|
|
||||||
|
const isRequireCall = (node, dependencyId, scope) =>
|
||||||
|
t.isCallExpression(node) &&
|
||||||
|
t.isIdentifier(node.callee, {name: 'require'}) &&
|
||||||
|
checkRequireArgs(node.arguments, dependencyId);
|
||||||
|
|
||||||
|
const isImport = (node, scope, patterns) =>
|
||||||
|
patterns.some(pattern => {
|
||||||
|
const importName = importMap.get(pattern.name) || pattern.name;
|
||||||
|
return isRequireCall(node, importName, scope);
|
||||||
|
});
|
||||||
|
|
||||||
|
const isImportOrGlobal = (node, scope, patterns, isWrappedModule) => {
|
||||||
|
const identifier = patterns.find(pattern => t.isIdentifier(node, pattern));
|
||||||
|
return (
|
||||||
|
(identifier &&
|
||||||
|
isToplevelBinding(scope.getBinding(identifier.name), isWrappedModule)) ||
|
||||||
|
isImport(node, scope, patterns)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkRequireArgs = (args, dependencyId) => {
|
||||||
|
const pattern = t.stringLiteral(dependencyId);
|
||||||
|
return (
|
||||||
|
t.isStringLiteral(args[0], pattern) ||
|
||||||
|
(t.isMemberExpression(args[0]) &&
|
||||||
|
t.isNumericLiteral(args[0].property) &&
|
||||||
|
t.isStringLiteral(args[1], pattern))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isToplevelBinding = (binding, isWrappedModule) =>
|
||||||
|
isGlobal(binding) ||
|
||||||
|
!binding.scope.parent ||
|
||||||
|
(isWrappedModule && !binding.scope.parent.parent);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
isPlatformOS,
|
||||||
|
isReactPlatformOS,
|
||||||
|
isPlatformSelect,
|
||||||
|
isReactPlatformSelect,
|
||||||
|
};
|
|
@ -13,26 +13,18 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const babel = require('babel-core');
|
const babel = require('babel-core');
|
||||||
|
const inlinePlatform = require('./inline-platform');
|
||||||
const invariant = require('fbjs/lib/invariant');
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
|
||||||
import type {Ast, SourceMap as MappingsMap} from 'babel-core';
|
import type {Ast, SourceMap as MappingsMap} from 'babel-core';
|
||||||
const t = babel.types;
|
const t = babel.types;
|
||||||
|
|
||||||
const React = {name: 'React'};
|
|
||||||
const ReactNative = {name: 'ReactNative'};
|
|
||||||
const platform = {name: 'Platform'};
|
|
||||||
const os = {name: 'OS'};
|
|
||||||
const select = {name: 'select'};
|
|
||||||
const requirePattern = {name: 'require'};
|
|
||||||
|
|
||||||
const env = {name: 'env'};
|
const env = {name: 'env'};
|
||||||
const nodeEnv = {name: 'NODE_ENV'};
|
const nodeEnv = {name: 'NODE_ENV'};
|
||||||
const processId = {name: 'process'};
|
const processId = {name: 'process'};
|
||||||
|
|
||||||
const dev = {name: '__DEV__'};
|
const dev = {name: '__DEV__'};
|
||||||
|
|
||||||
const importMap = new Map([['ReactNative', 'react-native']]);
|
|
||||||
|
|
||||||
const isGlobal = binding => !binding;
|
const isGlobal = binding => !binding;
|
||||||
|
|
||||||
const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
||||||
|
@ -40,49 +32,9 @@ const isFlowDeclared = binding => t.isDeclareVariable(binding.path);
|
||||||
const isGlobalOrFlowDeclared = binding =>
|
const isGlobalOrFlowDeclared = binding =>
|
||||||
isGlobal(binding) || isFlowDeclared(binding);
|
isGlobal(binding) || isFlowDeclared(binding);
|
||||||
|
|
||||||
const isToplevelBinding = (binding, isWrappedModule) =>
|
|
||||||
isGlobal(binding) ||
|
|
||||||
!binding.scope.parent ||
|
|
||||||
(isWrappedModule && !binding.scope.parent.parent);
|
|
||||||
|
|
||||||
const isRequireCall = (node, dependencyId, scope) =>
|
|
||||||
t.isCallExpression(node) &&
|
|
||||||
t.isIdentifier(node.callee, requirePattern) &&
|
|
||||||
checkRequireArgs(node.arguments, dependencyId);
|
|
||||||
|
|
||||||
const isImport = (node, scope, patterns) =>
|
|
||||||
patterns.some(pattern => {
|
|
||||||
const importName = importMap.get(pattern.name) || pattern.name;
|
|
||||||
return isRequireCall(node, importName, scope);
|
|
||||||
});
|
|
||||||
|
|
||||||
function isImportOrGlobal(node, scope, patterns, isWrappedModule) {
|
|
||||||
const identifier = patterns.find(pattern => t.isIdentifier(node, pattern));
|
|
||||||
return (
|
|
||||||
(identifier &&
|
|
||||||
isToplevelBinding(scope.getBinding(identifier.name), isWrappedModule)) ||
|
|
||||||
isImport(node, scope, patterns)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const isLeftHandSideOfAssignmentExpression = (node, parent) =>
|
const isLeftHandSideOfAssignmentExpression = (node, parent) =>
|
||||||
t.isAssignmentExpression(parent) && parent.left === node;
|
t.isAssignmentExpression(parent) && parent.left === node;
|
||||||
|
|
||||||
const isPlatformOS = (node, scope, isWrappedModule) =>
|
|
||||||
t.isIdentifier(node.property, os) &&
|
|
||||||
isImportOrGlobal(node.object, scope, [platform], isWrappedModule);
|
|
||||||
|
|
||||||
const isReactPlatformOS = (node, scope, isWrappedModule) =>
|
|
||||||
t.isIdentifier(node.property, os) &&
|
|
||||||
t.isMemberExpression(node.object) &&
|
|
||||||
t.isIdentifier(node.object.property, platform) &&
|
|
||||||
isImportOrGlobal(
|
|
||||||
node.object.object,
|
|
||||||
scope,
|
|
||||||
[React, ReactNative],
|
|
||||||
isWrappedModule,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isProcessEnvNodeEnv = (node, scope) =>
|
const isProcessEnvNodeEnv = (node, scope) =>
|
||||||
t.isIdentifier(node.property, nodeEnv) &&
|
t.isIdentifier(node.property, nodeEnv) &&
|
||||||
t.isMemberExpression(node.object) &&
|
t.isMemberExpression(node.object) &&
|
||||||
|
@ -90,24 +42,6 @@ const isProcessEnvNodeEnv = (node, scope) =>
|
||||||
t.isIdentifier(node.object.object, processId) &&
|
t.isIdentifier(node.object.object, processId) &&
|
||||||
isGlobal(scope.getBinding(processId.name));
|
isGlobal(scope.getBinding(processId.name));
|
||||||
|
|
||||||
const isPlatformSelect = (node, scope, isWrappedModule) =>
|
|
||||||
t.isMemberExpression(node.callee) &&
|
|
||||||
t.isIdentifier(node.callee.object, platform) &&
|
|
||||||
t.isIdentifier(node.callee.property, select) &&
|
|
||||||
isImportOrGlobal(node.callee.object, scope, [platform], isWrappedModule);
|
|
||||||
|
|
||||||
const isReactPlatformSelect = (node, scope, isWrappedModule) =>
|
|
||||||
t.isMemberExpression(node.callee) &&
|
|
||||||
t.isIdentifier(node.callee.property, select) &&
|
|
||||||
t.isMemberExpression(node.callee.object) &&
|
|
||||||
t.isIdentifier(node.callee.object.property, platform) &&
|
|
||||||
isImportOrGlobal(
|
|
||||||
node.callee.object.object,
|
|
||||||
scope,
|
|
||||||
[React, ReactNative],
|
|
||||||
isWrappedModule,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isDev = (node, parent, scope) =>
|
const isDev = (node, parent, scope) =>
|
||||||
t.isIdentifier(node, dev) &&
|
t.isIdentifier(node, dev) &&
|
||||||
isGlobalOrFlowDeclared(scope.getBinding(dev.name)) &&
|
isGlobalOrFlowDeclared(scope.getBinding(dev.name)) &&
|
||||||
|
@ -132,8 +66,8 @@ const inlinePlugin = {
|
||||||
|
|
||||||
if (!isLeftHandSideOfAssignmentExpression(node, path.parent)) {
|
if (!isLeftHandSideOfAssignmentExpression(node, path.parent)) {
|
||||||
if (
|
if (
|
||||||
isPlatformOS(node, scope, opts.isWrapped) ||
|
inlinePlatform.isPlatformOS(node, scope, opts.isWrapped) ||
|
||||||
isReactPlatformOS(node, scope, opts.isWrapped)
|
inlinePlatform.isReactPlatformOS(node, scope, opts.isWrapped)
|
||||||
) {
|
) {
|
||||||
path.replaceWith(t.stringLiteral(opts.platform));
|
path.replaceWith(t.stringLiteral(opts.platform));
|
||||||
} else if (isProcessEnvNodeEnv(node, scope)) {
|
} else if (isProcessEnvNodeEnv(node, scope)) {
|
||||||
|
@ -150,8 +84,8 @@ const inlinePlugin = {
|
||||||
const opts = state.opts;
|
const opts = state.opts;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isPlatformSelect(node, scope, opts.isWrapped) ||
|
inlinePlatform.isPlatformSelect(node, scope, opts.isWrapped) ||
|
||||||
isReactPlatformSelect(node, scope, opts.isWrapped)
|
inlinePlatform.isReactPlatformSelect(node, scope, opts.isWrapped)
|
||||||
) {
|
) {
|
||||||
const fallback = () =>
|
const fallback = () =>
|
||||||
findProperty(arg, 'default', () => t.identifier('undefined'));
|
findProperty(arg, 'default', () => t.identifier('undefined'));
|
||||||
|
@ -167,16 +101,6 @@ const inlinePlugin = {
|
||||||
|
|
||||||
const plugin = () => inlinePlugin;
|
const plugin = () => inlinePlugin;
|
||||||
|
|
||||||
function checkRequireArgs(args, dependencyId) {
|
|
||||||
const pattern = t.stringLiteral(dependencyId);
|
|
||||||
return (
|
|
||||||
t.isStringLiteral(args[0], pattern) ||
|
|
||||||
(t.isMemberExpression(args[0]) &&
|
|
||||||
t.isNumericLiteral(args[0].property) &&
|
|
||||||
t.isStringLiteral(args[1], pattern))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
type AstResult = {
|
type AstResult = {
|
||||||
ast: Ast,
|
ast: Ast,
|
||||||
code: ?string,
|
code: ?string,
|
||||||
|
|
Loading…
Reference in New Issue